Reputation: 55
In my component im trying to sync the received props with the current state in order to make it visible from outside (I know this is an anti-pattern, but I haven't figured out another solution to this yet. Im very open to suggestions!).
Anyways, this is what I've got:
export class PopupContainer extends React.Component {
state = {
show: false,
};
shouldComponentUpdate(nextProps, nextState) {
if (this.props.show === nextProps.show) return true;
return true;
}
componentDidUpdate(prevProps, prevState, snapshot) {
// if popup shown, fade it out in 500ms
if (this.props.show !== prevProps.show)
this.setState({ show: this.props.show });
if (this.state.show) {
setTimeout(() => this.setState({ show: false }), 2000);
}
}
render() {
return <Popup {...{ ...this.props, show: this.state.show }} />;
}
}
And in my external component I'm rendering the container :
<PopupContainer
show={this.state.popup.show}
message={this.state.popup.message}
level={this.state.popup.level}
/>
Now when I initially set this.state.show
to true
it works, but every successive assignment which is also true
without any false
assignment inbetween doesn't work. How do I force componentdidUpdate()
to fire anyways even if the props are the same value? shouldComponentUpdate()
didn't seem to solve the problem.
Thank you!
Edit: I noticed that the render()
method is only called in the parent element. It seems like as there is no change in properties for the child, react doesn't even bother rerendering the childern which somehow makes sense. But how can I force them to rerender anyways?
Upvotes: 5
Views: 2025
Reputation: 2614
This is kind of a hack, but it works for me.
In the child class
Add a property to state in constructor - let's call it myChildTrigger
, and set it to an empty string:
this.state = {
...
myChildTrigger: ''
}
then add this to componentDidUpdate
:
componentDidUpdate(prevProps) {
if(this.state.myChildTrigger !== this.props.myParentTrigger) {
// Do what you want here
this.setState({myChildTrigger: this.props.myParentTrigger});
}
}
In the parent class
Add a myParentTrigger
to state in constructor:
this.state = {
...
myParentTrigger: ''
}
In the render method, add it as a prop, like this:
<ChildClass ... myParentTrigger={this.state.myParentTrigger} />
Now you can trigger a call to componentDidUpdate
to execute whatever is inside the if-statement, just by setting myParentTrigger
to a new value, like:
this.setState({ myParentTrigger: this.state.myParentTrigger + 'a' });
Upvotes: 1