I'm having a heck of time with this. I do NOT want my child to re-render when the parents state changes. I've tried to use shouldComponentUpdate in the child ponent, but for some reason that's not even being invoked.
My issue is this. I have several charts on a grid, I want to update one of the charts configuration settings, which I pass as a prop to the ponent. The parent, which they all share, updates that childs config, but in the process, the config changes and thus they all re-render.
Why isn't shouldComponentUpdate being invoked? It gets invoked on the parent, so I'm assuming it is invoked where the state changes???
My code looks something like:
Parent - has selectDataType with setState Child1 - calls selectDataType which was passed down as a prop, which re-renders Child2 - no changes to it's props, but re-renders, which I need to stop
Parent:
selectDataType(e) {
e.stopPropagation();
var cellId = e.currentTarget.dataset.id;
var cellValue = e.currentTarget.childNodes[0].value;
var newCells = [];
newCells = this.state.cells.map(function (cell, i) {
var newObj = Object.assign({}, cell);
if (cellId == cell.id) {
newObj['dataType'] = cellValue;
}
return newObj;
});
this.setState({
cells: newCells
});
return;
}
Child1:
export default class Pie extends React.Component {
constructor(props) {
super(props);
this.create = this.create.bind(this);
}
shouldComponentUpdate() {
return false;
}
create() {
return {
//some data
}
}
render() {
return (
<div>
<ReactECharts
option={ this.create() }
style={{ position: "absolute", top: 0, bottom: 0, left: 0, right: 0, height: "100%" }}
theme="chalk"
notMerge={ true }
/>
</div>
)
}
}
Child2: exactly like Child1
I'm having a heck of time with this. I do NOT want my child to re-render when the parents state changes. I've tried to use shouldComponentUpdate in the child ponent, but for some reason that's not even being invoked.
My issue is this. I have several charts on a grid, I want to update one of the charts configuration settings, which I pass as a prop to the ponent. The parent, which they all share, updates that childs config, but in the process, the config changes and thus they all re-render.
Why isn't shouldComponentUpdate being invoked? It gets invoked on the parent, so I'm assuming it is invoked where the state changes???
My code looks something like:
Parent - has selectDataType with setState Child1 - calls selectDataType which was passed down as a prop, which re-renders Child2 - no changes to it's props, but re-renders, which I need to stop
Parent:
selectDataType(e) {
e.stopPropagation();
var cellId = e.currentTarget.dataset.id;
var cellValue = e.currentTarget.childNodes[0].value;
var newCells = [];
newCells = this.state.cells.map(function (cell, i) {
var newObj = Object.assign({}, cell);
if (cellId == cell.id) {
newObj['dataType'] = cellValue;
}
return newObj;
});
this.setState({
cells: newCells
});
return;
}
Child1:
export default class Pie extends React.Component {
constructor(props) {
super(props);
this.create = this.create.bind(this);
}
shouldComponentUpdate() {
return false;
}
create() {
return {
//some data
}
}
render() {
return (
<div>
<ReactECharts
option={ this.create() }
style={{ position: "absolute", top: 0, bottom: 0, left: 0, right: 0, height: "100%" }}
theme="chalk"
notMerge={ true }
/>
</div>
)
}
}
Child2: exactly like Child1
Share Improve this question asked May 8, 2018 at 22:14 stevenlacerdastevenlacerda 1,1873 gold badges10 silver badges21 bronze badges 7- shouldComponentUpdate() : Returning false does not prevent child ponents from re-rendering when their state changes. – dave Commented May 8, 2018 at 22:23
-
How do you render the children in the parent? A possible reason is not giving a static
key
property to the child ponents. If they're given, say, a random key every time they're rendered, then they'll pletely unmount and remount with its new parent properties. So the child ponent isn't updating, it's remounting. HenceshouldComponentUpdate
won't be called – Jayce444 Commented May 8, 2018 at 22:26 - Can you show us the parent's render? – Leandro Soares Commented May 8, 2018 at 22:32
- ahhhh...@Jayce444 that seems reasonable. Let me check it out and get back to you. – stevenlacerda Commented May 8, 2018 at 22:38
- 1 Thanks @Jayce444. It solved my problem too. Been pulling my hair out on this one. – snowykz Commented Jun 3, 2021 at 9:53
2 Answers
Reset to default 7Make sure your children are given a static key prop (as for all arrays of ponents). If they're given a random key, then when the parent re-renders it'll give all the children a new random key (different from their old one). This will make React think it's a pletely different ponent, so the existing one will pletely unmount and be remounted (with the new properties). So the child ponent isn't updating, it's remounting. Hence shouldComponentUpdate
won't be called.
You might find answers here, for both classes and hooks: ReactJS: setState on parent inside child ponent
Short answer for hooks would be:
- Send parent state and setState in child prop. Lets call those
parentState
andsetParentState
- In child ponent:
- have a
useEffect
which only does something when parentState is updated:
- have a
useEffect(() => {
props.parentStateSetter(childStateValueYouWantToTrack);
}, [props.parentState, childStateValueYouWantToTrack]);
You should check out the link for more information