user578895
user578895

Reputation:

React: Dynamically setting element keys

tl;dr -- How do I dynamically add a key to a React Element?


I have a React component that, when standing alone, has a static list of children:

<componentA>
  <child ... />
  <child ... />
  <child ... />
</componentA>

As the list is static there are no keys on any of the children as they're not needed.

Now I have another component that wraps this one and makes it's children dynamic:

function componentB(componentA) {
  return class extends React.Component {
    render() {
      const filteredChildren = // ... filter this.props.children

      return (<componentA>
        {filteredChildren}
      </componentA>)
    }
  }
}

As the children are now dynamic I need to add keys to them, but if I try something like:

React.Children.map((child, i) => {
  child.key = i;
  return child
});

it fails saying key is readonly. From this question it seems that cloneElement is a no-go as well. So is there a way to dynamically set a key?

Upvotes: 3

Views: 4432

Answers (2)

Abdennour TOUMI
Abdennour TOUMI

Reputation: 93173

Use cloneElement inside map :

React.Children.map(this.props.children, (child,  i) =>
      React.cloneElement(child, { key:  i })
 );

Known that the 2ⁿᵈ argument of React.cloneElement is the NEW props of the cloned element . One of those props is the key in this example.

Upvotes: 10

Justin M. Ucar
Justin M. Ucar

Reputation: 883

I had the same issue, so in your function, simply do this:

function componentB(componentA) {
  return class extends React.Component {
    render() {
      const filteredChildren = // ... filter this.props.children

      return (<componentA key={function_generating_random_strings()}>
        {filteredChildren}
      </componentA>)
    }
  }
}

Upvotes: 0

Related Questions