Reputation: 71
child component state like:
interface State {
data: { x: number; y: string };
}
// initial in constructor
this.state = {
data: {
x: 10,
y: 'sss',
},
};
when do setState
like:
const { data } = this.state;
data.x += 10;
this.setState({ data });
nextState
always equal this.state
in shouldComponentUpdate
, console log in shouldComponentUpdate
is:
next: {"data":{"x":20,"y":"sss"}}
this: {"data":{"x":20,"y":"sss"}}
I want to render child component only when child after setState
, instead of parent component render.
so, when parent component render, how to avoid child re-render
update:
find an answer, how to set nested state object:
Upvotes: 1
Views: 58
Reputation: 53894
The problem is that you mutating the current state and then comparing it with the next state.
export default class App extends React.Component {
state = {
name: 'hello',
data: {
x: 10,
y: 'sss'
}
};
shouldComponentUpdate(nextProps, nextState) {
console.log('this', this.state.data.x);
console.log('next', nextState.data.x);
const isRender = this.state.data.x !== nextState.data.x;
console.log('will render?', isRender);
return isRender;
}
render() {
const { name, data } = this.state;
// Dont mutate state
// data.x += 10;
return (
<FlexBox>
<Input
value={name}
onChange={e => this.setState({ name: e.target.value, data: data.x+10 })}
/>
</FlexBox>
);
}
}
In your sandbox example, fix shouldComponentUpdate
logic:
shouldComponentUpdate(nextProps, nextState) {
console.log('In should child update', nextState.data, this.state.data);
const willRender = nextState.data !== this.state.data;
console.log('will render?', willRender);
return willRender;
}
changeCurrentState = () => {
const { data } = this.state;
// Dont mutate state.
// data.x += 10;
// this.setState({ data });
this.setState({ data: { x: data.x + 10 } });
};
Upvotes: 1