I\'m still learning ReactJS. I\'m challenging myself to write a very basic todo app (as one does) and I\'m having an issue calling an onClick function.
var L
You should bind this
explicitly to the handleClick
function to be referring to the React component not the map function, so you can refactor your code as follow:
var items = list.map(renderListItem.bind(this));
And add renderListItem
method in your React class as follow:
renderListItem(item) {
return (
<li style={{borderBottom:'1px solid red'}}>
<label onClick={this.handleClick}>
<input type="checkbox" />
{item}
</label>
</li>
);
}
The second argument for the map function is a value to define the scope of
this
when executing the callback.:
.map( callback( currentValue, index, array), value_for_this/scope_to_run_in )
So you can modify your map
function as follows:
var items = list.map(function(item){
return (
<li style={{borderBottom:'1px solid red'}}>
<label onClick={this.handleClick}>
<input type="checkbox" />
{item}
</label>
</li>
);
}, this);
You could also use an arrow function which where
this
is implicitly bound:
var items = list.map((item) => {
return (
<li style={{borderBottom:'1px solid red'}}>
<label onClick={this.handleClick}>
<input type="checkbox" />
{item}
</label>
</li>
);
});
The problem you're running into is that your call to list.map
will invoke the passed function with a different this
than you have in your render
method.
An easy fix is to grab this
in the outer scope and stash it in a variable, then use that variable in your inline function.
render: function () {
var self = this;
// ^^^^^^^^^^^^^^^^
var list = this.props.items;
var items = list.map(function(item){
return (
<li style={{borderBottom:'1px solid red'}}>
<label onClick={self.handleClick}>
// ^^^^
<input type="checkbox" />
{item}
</label>
</li>
);
});
return (
<ul>{items}</ul>
)
}