-
Notifications
You must be signed in to change notification settings - Fork 7.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
getDerivedStateFromProps for asynchronous setState #1147
Comments
I think your first implementation is subtly broken because if
then the second This isn't related to your question but it's to demonstrate that the logic you seem to consider straightforward in the "before" example is a bit wrong. Regarding your specific question:
What makes you think so? I think https://jsfiddle.net/k4bwe6oy/5/ constructor(props) {
super(props);
this.state = { done: false, prevStatus: this.props.status }
this.doneTimeout = null;
}
componentDidUpdate(prevProps) {
if (prevProps.status === STATUS_LOADING && this.props.status === STATUS_READY) {
clearTimeout(this.doneTimeout);
this.setState({ done: true });
this.doneTimeout = setTimeout(() => {
this.setState({ done: false });
}, 1000);
}
}
componentWillUnmount() {
clearTimeout(this.doneTimeout);
} (I also fixed the first issue by keeping track of the timeout.) Perhaps you think that
In this case there's no performance concern (the component tree is very shallow). The user will not see the intermediate state because |
Both points make total sense. You are right, I thought that Really appreciate the response. |
No problem! |
I am inquiring about what is hopefully an undiscussed use case related to the
componentWillReceiveProps
->getDerivedStateFromProps
changes. I read through the blog post and threads like #721.The use case is a button which says either "Save", "Saving", or "Saved!". The idea is that the button component is shared across apps, which pass a prop to the button indicating whether the app is currently saving. The button component's purpose is to encapsulate the logic that temporarily shows the text "Saved!", when saving finishes.
This can be handled with
componentWillReceiveProps
pretty simply: https://jsfiddle.net/Luktwrdm/1137/ - if the status prop changes in a certain way, show the "Saved!" text, and then use a timeout to later change itself back to a ready state ("Save").Without
componentWillReceiveProps
, this case seems to require bothgetDerivedStateFromProps
andcomponentDidUpdate
, and an extra key in the state: https://jsfiddle.net/Luktwrdm/1138/ - You can't do it all indidUpdate
because otherwise the component would flash with the incorrect copy for a split second. And you can't do it all ingetDerivedStateFromProps
because it's static.The purpose of this issue is to clarify - is this (the second fiddle) now the best way to handle such a situation? Am I missing some higher level structural way to avoid this complexity?
I can imagine other use cases, like notifications, where it might make sense for a component to react to its props changing by making a temporary state change. Is that an anti-pattern? Or something worth covering in the docs?
The text was updated successfully, but these errors were encountered: