Why do I have to use arrow function in event handler of react?
without the arrow function, every button click renders the page again, which sets the state, then it renders again, and sets the state, then it renders again. infinite loop
the arrow function recreates that function once when it mounts/updates.
read more here https://reactjs.org/docs/faq-functions.html
Using arrow functions and event.target with event handlers to get scope instead of normal functions and the this keyword?
However, with so many articles recommending against using arrow functions in event handlers, I am wondering if there are any disadvantages to my approach that I may have missed?
It doesn't look like you have missed anything. You are not using any of the "features" that make arrow functions different from "normal" functions.
You are
- not using
this
- not using
arguments
- not calling the function with
new
(and the browser doesn't either)
so you can choose either form.
If I remember correctly event.target
didn't exist in older versions of Internet Explorer (< 9) (instead it was event.srcElement
), but if you are using an arrow function you probably don't care about deprecated browsers ;)
Bind vs Arrow Function when passing onChange props (React)
Since it is only using a reference to the function, we are not causing a re-render each time
You're wrong.
The bind
method returns a new function (so will trigger a re-render).
To avoid re-renders, make use of the useCallback
hook.
Or, since you don't appear to be making use of this
inside myFunction
(otherwise () => myFunction()
would break it), just pass myFunction
itself without creating a new function.
onClick={myFunction}
Arrow function in AddEventListener not working
Because this
in your arrow function doesn't point to the <input>
element. It points to the scope wherein the arrow function was created. Read about it on MDN.
EDIT: Answer to question in comments
In your case, if you want to use an arrow function in your event listener, just re-use the hider
variable instead of this
:
hider.addEventListener('click', () => {
// use "hider" instead of "this"
hider.hidden = true;
});
Taking it further
If you'd want to create an "element-agnostic" event handler, make it a higher order function that takes in the element to hide as a parameter and that returns an (here: anonymous) handler function. If this sounds cryptic to you, here's some example code:
const makeHideHandler = (element) => { // higher order function
return () => { // event handler function
element.hidden = true; // action to perform
};
};
With this, you can write a one liner to add the listener:
hider.addEventListener('click', makeHideHandler(hider));
If you want to know why it works, google for "closures".
However, the real strength of the higher order function approach becomes visible if you have more than one element that should hide the same (or other!) element(s). Consider the following:
Let's say, you have multiple buttons that, when pressed, should hide the same element. It's easy peas with makeHideHandler
:
// grab all "button" elements
const hideButtons = document.querySelectorAll('.hide-button');
// grab the element to hide
const elemToHide = document.querySelector('.hide-me');
// make the handler, pass in the element that should be hidden
const hideHandler = makeHideHandler(elemToHide);
// add listeners to the buttons
hideButtons.forEach((button) => {
button.addEventListener('click', hideHandler);
});
Or to create buttons that hide themself after pressing:
const hideButtons = document.querySelectorAll('.hide-button');
hideButtons.forEach((button) => {
button.addEventListener('click', makeHideHandler(button)); // <-- pass in the button element
});
How does event handlers with arrow functions achieve context binding
As the MDN docs states
An arrow function does not have its own this; the this value of the
enclosing execution context is used
So you would think of
onClick={(e) => this.goToStore(e)}
as being an anonymous function which can be written as
(e) => {
return this.goToStore(e)
}
Now here in this anonymous function this
refers to the lexical context of the render function which in turn refers to the React Class instance.
Now
Context is most often determined by how a function is invoked. When a function is called as a method of an object, this is set to the object the method is called on:
var obj = {
foo: function() {
return this;
}
};
obj.foo() === obj; // true
The same principle applies when invoking a function with the new operator to create an instance of an object. When invoked in this manner, the value of this within the scope of the function will be set to the newly created instance:
function foo() {
alert(this);
}
foo() // window
new foo() // foo
When called as an unbound function, this will default to the global context or window object in the browser.
So here since the function is called like this.goToStore()
this inside it will refer to the context of React component.
However when you write onClick={this.goToStore}
, the function is not executed but a reference of it is assigned to the onClick function, which then later invokes it, causing this
to be undefined inside the function as the function runs on the context of the window
object.
Now even though onClick={(e) => this.goToStore(e)}
works, whenever render is called a new function instance is created. In your case its easy to avoid, just by created the function goToStore using arrow function syntax.
goToStore = (e) => {
}
Check the docs for more details on this
Related Topics
Jquery - Setting the Selected Value of a Select Control via Its Text Description
Concrete JavaScript Regular Expression for Accented Characters (Diacritics)
How to Get the Non-Enumerable Inherited Property Names of an Object
Document.Createelement("Script") Synchronously
Javascript: How to Join/Combine Two Arrays to Concatenate into One Array
Why Don't We Just Use Element Ids as Identifiers in JavaScript
Display Posts in Descending Posted Order
What Does (Function($) {})(Jquery); Mean
Does React Keep the Order for State Updates
Passing Environment-Dependent Variables in Webpack
Convert Utc Epoch to Local Date
Warn User Before Leaving Web Page with Unsaved Changes
How to Check for an Undefined or Null Variable in JavaScript
Why Is My Function Call That Should Be Scheduled by Settimeout Executed Immediately