-
Notifications
You must be signed in to change notification settings - Fork 570
async-safe, static lifecycle hooks #6
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
Changes from 1 commit
9818f57
839547f
b7189cc
aad6845
99988da
4a34d25
902d4b3
3df7ce6
1864c93
428758b
cfcb7e8
536084d
a1431a4
3c6132e
4425dbe
67272ce
c7f6728
bb2d246
8618f70
8f6c20e
e05e317
7042a2a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14,7 +14,7 @@ At a high-level, I propose the following additions/changes to the component API. | |
|
|
||
| ```js | ||
| class ExampleComponent extends React.Component { | ||
| static deriveStateFromProps(props, state, prevProps) { | ||
| static getDerivedStateFromNextProps(nextProps, prevProps, prevState) { | ||
| // Called before a mounted component receives new props. | ||
| // Return an object to update state in response to prop changes. | ||
| // Return null to indicate no change to state. | ||
|
|
@@ -172,10 +172,10 @@ class ExampleComponent extends React.Component { | |
| derivedData: computeDerivedState(this.props) | ||
| }; | ||
|
|
||
| static deriveStateFromProps(props, state, prevProps) { | ||
| if (props.someValue !== prevProps.someValue) { | ||
| static getDerivedStateFromNextProps(nextProps, prevProps, prevState) { | ||
| if (nextProps.someValue !== prevProps.someValue) { | ||
| return { | ||
| derivedData: computeDerivedState(props) | ||
| derivedData: computeDerivedState(nextProps) | ||
| }; | ||
| } | ||
|
|
||
|
|
@@ -375,11 +375,11 @@ The purpose of this method is to initiate asynchronous request(s) as early as po | |
|
|
||
| Avoid introducing any non-idempotent side-effects, mutations, or subscriptions in this method. For those use cases, use `componentDidMount`/`componentDidUpdate` instead. | ||
|
|
||
| ### `static deriveStateFromProps(props: Props, state: State, prevProps: Props): PartialState | null` | ||
| ### `static getDerivedStateFromNextProps(nextProps: Props, prevProps: Props, prevState: Props): PartialState | null` | ||
|
||
|
|
||
| This method is invoked before a mounted component receives new props. Return an object to update state in response to prop changes. Return null to indicate no change to state. | ||
|
||
|
|
||
| Note that React may call this method even if the props have not changed. If calculating derived data is expensive, compare new and previous prop values to conditionally handle changes. | ||
| Note that React may call this method even if the props have not changed. If calculating derived data is expensive, compare next and previous props to conditionally handle changes. | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @bvaughn The PR for React included
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The wording here is a bit ambiguous but I think that's okay. Current and previous props can be compared, as shown in this example There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, previous props in this case means props that have been synced to the local state and can be access via There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So @bvaughn does this mean that, given our previous conversation, I have to "sync" all my props to state in order to compare previous props with the new props? Feels like I'm missing something here.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not all
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
It's a bit different though. You're not storing a "mirrored" version, you're storing the previous version. Which is a special case of an accumulation (that happens to completely discard the current value). Accumulation is exactly the purpose of I guess one could say that a "mirrored" version would also be a special case of accumulation (that discards the previous value) but that's sophism IMO :-) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Yeah, I see what you mean. I just feel that it muddies the message of "don't put unnecessary stuff in state" where "necessary" no longer precisely means "used in Anyway I see the trade-off, and I appreciate your willingness to explain! 😊
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
We might actually revisit this one ^^ With async React it might not be safe to put certain things on the instance fields. See facebook/react#10580. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @bvaughn @gaearon I've tried to flesh out what I mean using a Typescript example - see this gist - to compare the two approaches. I've extracted this example from a real life component that has more props, but hopefully you get the idea: any component would have to follow a similar pattern. There are three files in the gist:
Notice file 2 is using a slightly different signature to the proposed in my last response; I agree with @gaearon the nullability issue is best avoided, hence Does the diff help to show what I mean about the boilerplate required when we have to "sync" to state? Thanks
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Previous props would still need to be null or undefined in this case, no? Or even more confusingly, they would equal current props. Anyway~ thanks for the feedback, Paul. I understand and appreciate your concern about verbosity. 🙇 This proposal was discussed in length in December, accepted, and merged into the React repo a couple of weeks ago. I'm going to lock down the thread at this point because I think we've already committed to this API. Hope you understand! |
||
|
|
||
| React does not call this method before the intial render/mount and so it is not called during server rendering. | ||
|
||
|
|
||
|
|
@@ -395,7 +395,7 @@ This method will log a deprecation warning in development mode recommending that | |
|
|
||
| ### `componentWillReceiveProps` -> `unsafe_componentWillReceiveProps` | ||
|
|
||
| This method will log a deprecation warning in development mode recommending that users either rename to `unsafe_componentWillReceiveProps` or use the new static `deriveStateFromProps` method instead. It will be removed entirely in version 17. | ||
| This method will log a deprecation warning in development mode recommending that users either rename to `unsafe_componentWillReceiveProps` or use the new static `getDerivedStateFromNextProps` method instead. It will be removed entirely in version 17. | ||
|
|
||
| # Drawbacks | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about simple
I think it's pretty neat. Keeping static user methods doesn't make sense. So why don't keep these names simple and fast for write?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't feel strongly about the name
getDerivedStatevsgetDerivedStateFromNextProps. If others do, they're welcome to weigh in.