Reputation: 151
I have the following code.
var ImageList = React.createClass({
getComponent: function(index){
console.log(index);
},
render: function() {
var results = this.props.data;
return (
<div className="row">
{results.map(function(result) {
return(
<a className="th medium-3 columns" href="#" onClick= {this.getComponent.bind(this, 1)}>
<img alt="Embedded Image" key={result.id} src={"data:" + result.type + ";" + "base64," + result.image} />
</a>
)
})}
</div>
);
}
});
The second return function basically loops an array of images and shows them. I wanted an OnClick
event when clicked should trigger the getComponent
method. However if the OnClick
event is within the array loop it throws the following error:
Uncaught TypeError: Cannot read property 'getComponent' of undefined.
However if i use the same code and just add the onClick
even after the looping function like below:
var ImageList = React.createClass({
getComponent: function(index){
console.log(index);
},
render: function() {
var results = this.props.data;
return (
<div className="row">
{results.map(function(result) {
return(
<img alt="Embedded Image" key={result.id} src={"data:" + result.type + ";" + "base64," + result.image} />
)
})}
<a className="th medium-3 columns" href="#" onClick= {this.getComponent.bind(this, 1)}>
</div>
);
}
});
Ends up working fine. But since i need to keep a unique id for each image only then can i complete the remaining function of getComponent
the second method isn't much use for me. Hence is there any way to make it work within the Loop?
Upvotes: 1
Views: 2019
Reputation: 595
You can use ES6 arrow functions to automatically preserve this context:
results((result) => { ... })
or just pass this
as second param to the map
:
results(function(result) { ... }, this)
Upvotes: 0
Reputation: 3796
Your scope changes within the .map
method:
{results.map(function(result) {
// `this` is different inside this anonymous function
})}
What you want to do is either use ES6' fat arrow syntax, which automatically creates an anonymous function with the same scope, or store the current scope of this in a variable:
ES6 Fat Arrow (read more here):
render: function() {
var results = this.props.data;
return (
<div className="row">
{results.map( (result) => {
return(
<a className="th medium-3 columns" href="#" onClick={that.getComponent.bind(that, 1)}>
<img alt="Embedded Image" key={result.id} src={"data:" + result.type + ";" + "base64," + result.image} />
</a>
)
})}
</div>
);
}
});
Note that you'll need a transpiler — such as babel.io — to change this into ES2015 which browsers currently understand to run. This is considered "best practice", as ES6/7 brings better functionality to JS.
Storing a reference to this:
render: function() {
var results = this.props.data,
that = this;
return (
<div className="row">
{results.map(function(result) {
return(
<a className="th medium-3 columns" href="#" onClick={that.getComponent.bind(that, 1)}>
<img alt="Embedded Image" key={result.id} src={"data:" + result.type + ";" + "base64," + result.image} />
</a>
)
})}
</div>
);
}
});
Upvotes: 1