Suppose that I have a function generateList()
that updates the state and mapping it to an onClick to a <li>.
<li className="some-classname"}
onClick={this.generateList('product')}> Product </li>
There are times that I encounter errors like:
Warning: setState(...): Cannot update during an existing state transition (such as within
render). Render methods should be a pure function of props...
And such. I mined the internet for answers for this, and came upon such answer like:
<li className="some-classname"}
onClick={this.generateList.bind(this, 'product')}> Product </li>
But I saw one answer too (in Github, but can't seem to find it) that
<li className="some-classname"}
onClick={() => this.generateList('product')}> Product </li>
What's the major difference? Which is more appropriate and efficient? And what's the reason that we should use such .bind
and () =>
when mapping a function to an onClick
or as a property of a React component (which I mostly use it)?
The () => { ... } is the function. It's an ES6-style "arrow" function expression. These are like function expressions ( tick = function() { ... } ) except that the this value within the function is inherited from the context in which it's defined rather than being set when the function is called.
Unlike regular functions, arrow functions do not have their own this . The value of this inside an arrow function remains the same throughout the lifecycle of the function and is always bound to the value of this in the closest non-arrow parent function.
The bind() is an inbuilt method in React that is used to pass the data as an argument to the function of a class based component.
It's a new feature that introduced in ES6 and is called arrow function. The left part denotes the input of a function and the right part the output of that function.
If you try:
<li className="some-classname"}
onClick={this.generateList('product')}> Product </li>
That function will be executed on every render - which can produce an additional render, which is what throws the error. What we want is to define a function that will be called later when onClick
is fired.
The second one is defining a method and .bind
is binding the context of the React class this
to the method. Note that the bind
function returns a copy of a function - So this doesn't call the function, just defines it for the onClick
handler to use.
The last one:
<li className="some-classname"}
onClick={() => this.generateList('product')}> Product </li>
This defines an anonymous function but, similar to the second implementation, does not call it. Only when onClick
is fired is it called. However in some cases using an anonymous function can cause performance issues. That anonymous function will be defined on every render - and if you have a component that is re-rendering very often it can hurt the performance of your application. If you are sure that the component will not be rendered often, an anonymous function should be fine for convenience.
Additionally when using bind you can declare it in the component class constructor like this:
constructor(props) {
super(props);
this.state = {
// your state
};
this.generateList = this.generateList.bind(this);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With