React onClick function in map function
Use an arrow function as the function given to map
instead and this
will be what you expect:
if (this.props.data) { var recipes = this.props.data.map((recipe, i) => { return <div key={i} className="col-8 offset-col-1 f-l relative m-t-10"> <div className="col-6 f-l"> <p className="col-8 f-l">{recipe.title}</p> <button className="f-l" onClick={this.handleClick}>Voir la recette</button> </div> </div>; });}
Why this is the case is explained in detail here. Arrow functions don't provide their own this
binding, but instead retains the this
value of the enclosing lexical context.
This is how I would tackle a similar situation.
import React from "react";import ReactDOM from "react-dom";const stuff = ["one", "two", "three"];class App extends React.Component { constructor(props) { super(props); this.state = { isToggleOn: true }; this.handleClick = this.handleClick.bind(this); } handleClick(val) { console.log(val); } getStuff() { var elements = stuff.map((value, key) => { return ( <li key={key} onClick={() => this.handleClick(value)}> {value} </li> ); }); return elements; } render() { return <ul>{this.getStuff()}</ul>; }}const rootElement = document.getElementById("root");ReactDOM.render(<App />, rootElement);
here is the sandbox -> https://codesandbox.io/embed/1rqw081oj7
You have to use this
in map arguments or arrow function.
this.props.data.map(function(recipe, i) { return <div key={i} className="col-8 offset-col-1 f-l relative m-t-10"> <div className="col-6 f-l"> <p className="col-8 f-l">{recipe.title}</p> <button className="f-l" onClick={this.handleClick}>Voir la recette</button> </div> </div>; }, this)
Why?
Read here.
If a
thisArg
parameter is provided to map, it will be used as callback'sthis
value. Otherwise, the value undefined will be used as its this value.
For a better undestanding of this
scope check here. Explains what are in this
in different context like Simple function call, as an object method, as arrow function, etc. Also explain how control the scope thanks to bind
, call
and apply
.