Ad

Modify React Child Component Props After Render

- 1 answer

Here's a simple example:

copyButton = <SomeReactComponent title="My Button" />

this.clipboard = new Clipboard('button#copy-button');
this.clipboard.on('success', () => { 
    this.copyButton.props.title = "Copied!";
});

render = () => {
    return (
        ...
        { this.copyButton }
        ...
    );
}

Using Clipboard.js, when my button is pressed, I copy some text to the clipboard. On a successful copy, I want to change the title of my copy button to reflect that. The button component, which I keep a reference to, has already been rendered and this.copyButton.props.title obviously doesn't work because components are immutable.

How then, would I go about changing the value of title on my button? I know I could have a state property in the parent component but I'd rather avoid that to keep my parent component complete stateless. Could I simply reassign this.copyButton inside the success callback (I tried that but no luck)?

Speaking more generally, how should parent components update their children's props if at all? Is using state really the only way?

Note: I'm using ES6 if that matters.

Ad

Answer

Considering that you're trying to update the state of the button's text, not using react state in some form (in the parent or child component) will probably feel a bit hacky. However, it is possible. The initial method that comes to mind is to use React.cloneElement to create a new version of copyButton with the title prop that you want. Then use this.forceUpdate to rerender the parent component with the update child component. Something like this:

this.clipboard.on('success', () => { 
    this.copyButton = React.cloneElement(this.copyButton, {
        title: 'Copied!'
    });
    this.forceUpdate();
});

https://facebook.github.io/react/docs/top-level-api.html#react.cloneelement

That being said, using state in this case would almost certainly be better both for readability and runtime (cloning elements and forcing a re-render isn't cheap).

Ad
source: stackoverflow.com
Ad