⚠️ This lesson is retired and might contain outdated information.

Use React.cloneElement to Extend Functionality of Children Components

Joe Maddalone
InstructorJoe Maddalone

Share this video with your friends

Send Tweet
Published 7 years ago
Updated 2 years ago

We can utilize React.cloneElement in order to create new components with extended data or functionality.

[00:00] In a number of interfaces, you'll find yourself wanting to extend the functionality or properties of your children components.

[00:08] To illustrate this, I've got a component called buttons and its children are these three buttons, each with a value a, b, and c. Our Buttons component has a state of selected. By default that's set to none. We've got a selectItem function, which updates that state.

[00:26] Right now, we're simply setting items to this prop's children. We're outputting in H2, that says you have selected, and then whatever the state is. Then, we output those items below it.

[00:35] We have that here. You have selected none, our default state. Then, what I want to do is each time you click on one of these, I want it to update that state. This is a common practice. You'd see this with a tabbed interface or some sort of navigational component or even a radio group.

[00:53] To add that functionality, we're going to use react.children to iterate over these guys, we're going to map over those. We're going to pass into that our props.children, and to keep this on the screen, I'm just going to have a iterator function that we'll create right here. Let iterator function equal...it's going to take in the child.

[01:14] At this point, we might think we could do something like child.onClick equals, or whatever, but you can't actually do that, because props.children isn't the actual children.

[01:28] It's a descriptor of the children, you don't actually have anything to change. You can't change the props, you can't add any functionality, you can't do anything with it. You can only read from it.

[01:38] In order to modify these, we actually need to create new elements. We can do that with react.cloneElement. Into that, we're going to pass our child.

[01:51] Then, the second argument is how we want to extend that. It's an object. We're going to say onClick is equal to this.selectItem. We'll bind that to this. We'll pass in the child props of value.

[02:09] Try that out. You have selected none. You have selected c, b, a.

~ 7 years ago

Up until now I really liked this series. But does this example not breaks with the whole idea of React and the Virtual DOM?

Each time a button is clicked, all thee buttons must be cloned and the whole screen re-rendered. That seems very in-efficient?

Control Group
Control Group
~ 7 years ago

If your changes to the children do not rely on an updated state (similar to this lesson), you can make those changes in the componentWillMount() method so they only happen the first time the component is rendered. Subsequent renderings will already have the updated children.

~ 6 years ago

I am wondering why does the syntax 'this.setState({selected})' (inside selectItem function) working correctly? Should it be 'this.setState({selected: selected})'?