Let's say we have a component called MyChildComponent which would be used for displaying a number list and also the ability to add a random number into the list via button click inside MyChildComponent. When button clicks, only MyChildComponent get re-render because only the state of MyChildComponent gets updated.
public class MyParentComponent extends React.Component {
const numsInParent = [0,1,2];
render() {
return <MyChildComponent nums="numsInParent " />);
}
}
public class MyChildComponent extends React.Component {
const { nums } = this.props;
state = { nums: this.props.nums };
handleChange = ()=> {
this.setState({ nums: {...nums, random()} });
};
render() {
return (
<button onClick="this.handleChange">Add<button>
<ul>
nums.map((num) =><li>{num}</li>)
</ul>);
}
}
However, oftentimes I was told we should not do as above design. We should have the parent component passing the nums
and also a function into child component props
, instead of implementing the actual method directly inside the child component, it would be done in parent component and value should be updated through child component props, which is so-called controlled component, like
public class MyParentComponent extends React.Component {
addNum() {
numsInParent = {...numsInParent, random()};
}
render() {
return <MyChildComponent nums="numsInParent " addNum="this.addNum" />);
}
}
public class MyChildComponent extends React.Component {
const { nums, addNum } = this.props;
handleChange = ()=> {
// child just call parent to do the real work
this.addNum();
};
render() {
return (
<button onClick="this.handleChange">Add<button>
<ul>
nums.map((num) =><li>{num}</li>)
</ul>);
}
}
Doing this way, when button click inside the child component, it would cause both parent and child component to get re-render in a way of child -> parent -> child, correct? So what would be the benefit of this design instead of the first one, would it cause any performance impact? I've seen example project that has a structure as
ComponentA(actual method) -> ComponentB -> ComponentC -> ... ComponentX
,
In order to figure out how something getting changed in ComponentX, we need to go all the way up to where the actual method being declared in ComponentA, does it also mean when something changed triggered in ComponentX, all Component from A, B, C to X will get a re-render? Does it worth that?