Reputation: 1488
React's documentation recommends passing functions as properties to child components in order to alter state variables of the parent. I'm finding this design to be a little cluttered on parents that hold lots of differing child components.
I started doing this:
constructor(props) {
super(props);
const that = this;
this.state = {
parentData : '',
setState : function(obj) { // <--
that.setState(obj)
}
};
}
render() {
<Child prop={this.state} />
}
Then in the child when I need to alter parent state:
childFunction() {
props.setState({ parentData: 'new data'})
}
Are there any downsides to this implementation?
Upvotes: 1
Views: 4658
Reputation: 35501
One thing you shouldn't do is actually store this function on the state
of the parent component but passing a function from the parent to the child that might eventually update parent's state is a valid and frequently used pattern in React.
const Child = ({ updateParent }) => (
<div id="child">
<button onClick={() => updateParent(Math.random())}>
Update Parent
</button>
</div>
);
class Parent extends React.Component {
constructor(props) {
super(props);
this.state = {
data : ''
};
}
render() {
return (
<div id="parent">
<h3>Data: {this.state.data}</h3>
<Child updateParent={(data) => this.setState({ data })} />
</div>
)
}
}
ReactDOM.render(
<Parent />,
document.querySelector('#example')
)
#parent {
height: 150px;
padding: 5px;
background: olivedrab;
color: #fff;
}
#parent:before {
content: 'Parent';
}
#child {
color: #000;
padding: 5px;
height: 50px;
background: lightgreen;
}
#child:before {
content: 'Child';
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="example"></div>
Upvotes: 3
Reputation: 468
One large downside is that it's much harder to track down where the state is being updated once your application starts to grow.
Upvotes: 2