Why in the method filter
do I have to use .bind(this)
as follows: onChange={this.filter.bind(this)}
, instead of just using the method filter
without .bind(this)
as in onChange={this.filter}
?
export default class TodoList extends React.Component {
filter(event) {
this.props.store.filter = event.target.value
}
render() {
return <div>
<h1>toDos</h1>
<input className="filter" onChange={this.filter.bind(this)} />
</div>
}
}
That's a javascript restriction, because the parameter you pass to the event handler
onChange
can come from any source and not necessarily from the current component. Take the following example where the functionfilter
is defined in a component that uses aTodoList
:What should be for this case, within the context of the function
filter
, the value ofthis
? The componentTodoApp
orTodoList
?So ES6 forces you to manually specify what the context for
this
. For the example described, if you wanted it tothis
be you wouldTodoApp
use:And if you wanted it to be
TodoList
, you would use:A cleaner way to do this is to define them
bind
inside the component's constructor, rather than inline:Another way, which you can find in several react examples on the internet, is to use
React.createClass
, which internally brings some syntactic sugar to save you from doingbind
it yourself:Note that ES5 is being used here, unlike when you extend your class since
React.Component
it is ES6. Despite the fact that basically they do the same thing, there are other subtle differences between the two, which you can consult in this article .One last option would be to use an
=>
ES6 arrow, which does anbind(this)
internally:however, if you intend to pass parameters to your function (for example )
onChange={this.filter('name')}
, you will need to be extra careful with the operator=>
. Your function should look like this:In ES6 there is the Arrow operator that allows you to 'binde' 'this' (Execution Context Immediately Above) in a more natural way instead of doing it manually in the constructor.
Additionally, it is not a restriction of ES6, the problem can be observed in previous versions as well as the bind() function that is defined in the prototype.
The syntactical enhancement is the one introduced by ES6 with the Arrow operator mentioned above, React does the work for you of assigning the class as a value to the 'this' keyword for you only in functions defined in React.Component like render functions, componentDidMount etc, however if you define your own functions in the child class of React.Component you have to set the value of 'this' for each function manually using the Arrow operator.
Additionally you must understand that in javascript 'this' works differently than other languages, in javascript 'this' takes the value of the immediately superior execution context and not that of the class, for this reason this will not always take the value of the class where you define the function and you have to set it manually.