Question

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?

Was it helpful?

Solution

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

OTHER TIPS

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>
  );
}

We can access data with Data Attributes

// 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...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top