Skip to content

Instantly share code, notes, and snippets.

@kujon
Last active August 9, 2016 13:38
Show Gist options
  • Save kujon/5c9974ca6f967bfef044f409fb93610a to your computer and use it in GitHub Desktop.
Save kujon/5c9974ca6f967bfef044f409fb93610a to your computer and use it in GitHub Desktop.
Control Delegation
class Child extends React.Component {
static defaultProps = {
type: 'text',
onChange: () => {},
value: ''
}
render() {
return <input {...this.props} />;
}
}
class Container extends React.Component {
constructor(props) {
super(props);
this.state = {
value: 'Initial value'
};
}
handleChange = e => {
this.setState({
value: e.target.value
});
}
render() {
const {children} = this.props;
const {value} = this.state;
return <div>
{React.Children.map(children, child => React.cloneElement(child, {onChange: this.handleChange, value}))}
</div>;
}
}
// In this example, <Container /> is going to be in charge of controlling <Child />.
ReactDOM.render(
<Container>
<Child />
</Container>,
document.getElementById('controlled-by-parent')
);
// In this example, <Container /> should stop controlling the <Child />
// (ideally by the virtue of <Child />'s props overriding props specified in <Container />'s `render` method).
// Crap implementation would be React.cloneElement(child, {onChange: this.handleChange, value, ...child.props});
// but that doesn't allow for the `controlled-by-parent` scenario working when `defaultProps` are present
// and is probably v. unidiomatic.
// Any ideas on how to make it work?
ReactDOM.render(
<Container>
<Child value={someValue} onChange={someHandler} />
</Container>,
document.getElementById('controlled-from-outside')
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment