Reputation: 11378
I am aware that dynamic children of a component must have a unique key
as the following (modified example from official docs):
render: function() {
var results = this.props.results;
return (
{results.map(function(result) {
return <ChildComponent type="text" key={result.id} changeCallback={this.props.callbackFn}/>;
})}
);
}
Considering that ChildComponent
is another React component nested here, with a render
method as bellow
render: function() {
var results = this.props.results;
return (
<div className="something">
<input type="text" onChange={this.props.changeCallback} />
</div>
);
}
is there any way to access the key when callbackFn(event)
is called?
Upvotes: 27
Views: 22972
Reputation: 23737
// ChildComponent.js
render: function() {
var results = this.props.results;
return (
<div className="something">
<input
type="text"
onChange={this.props.changeCallback}
data-key={this.props.key} // "key" was passed as props to <ChildComponent .../>
/>
</div>
);
}
Now; in your changeCallback
method; you can access this data
:
// ParentComponent.js
(evt) => {
console.log(evt.target.dataset.key);
}
Good Luck...
Upvotes: 1
Reputation: 751
Although the first answer is correct this is considered as a bad practice since:
A bind call or arrow function in a JSX prop will create a brand new function on every single render. This is bad for performance, as it will result in the garbage collector being invoked way more than is necessary.
Better way:
var List = React.createClass({
handleClick (id) {
console.log('yaaay the item key was: ', id)
}
render() {
return (
<ul>
{this.props.items.map(item =>
<ListItem key={item.id} item={item} onItemClick={this.handleClick} />
)}
</ul>
);
}
});
var ListItem = React.createClass({
render() {
return (
<li onClick={this._onClick}>
...
</li>
);
},
_onClick() {
this.props.onItemClick(this.props.item.id);
}
});
Source: https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-no-bind.md
Upvotes: 36
Reputation: 44880
Partially apply the function callback by using JavaScript's native bind
. This is mentioned in React's "Communicate Between Components" doc:
callbackFn: function(key) {
// key is "result.id"
this.props.callbackFn(key);
},
render: function() {
var results = this.props.results;
return (
<div>
{results.map(function(result) {
return (
<ChildComponent type="text" key={result.id}
changeCallback={this.callbackFn.bind(this, result.id)} />
);
}, this)}
</div>
);
}
Upvotes: 22