-
-
Notifications
You must be signed in to change notification settings - Fork 10.6k
Deprecated lifecycles #6341
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
Deprecated lifecycles #6341
Conversation
Moving invariant calls and other things that used to be in cWM into the constructor so that the behavior is the same as before, which also gets all the tests to pass
// Do this here so we can setState when a <Redirect> changes the | ||
// location in componentDidMount. This happens e.g. when doing | ||
// server rendering using a <StaticRouter>. | ||
this.unlisten = history.listen(() => { |
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.
The listener should be done in a componentDidMount. This will fire during server rendering and even if the component never gets mounted.
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.
The challenge with having it in cDM (which is where I had it originally) is that -- from what I found and the tests that failed -- React doesn't guarantee the order of whether a parent or child's cDM is fired first. Which means that the Redirect
component doesn't work, since the logic for redirection happens in cDM as well.
Maybe I could look at putting it in both places and only running if it's in a static router or something? Not sure. Any ideas?
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.
The React blog has some info on this: https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html#adding-event-listeners-or-subscriptions
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.
@timdorr from what I'm reading, they recommend using cDM. Yet that doesn't solve the issue I mentioned above.
I pushed up an alternative solution, what do you think of it?
@@ -90,7 +90,7 @@ class StaticRouter extends React.Component { | |||
|
|||
handleBlock = () => noop; | |||
|
|||
componentWillMount() { | |||
componentDidMount() { |
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.
StaticRouter is mainly for server rendering, so this lifecycle method won't fire on the server. It should be in a constructor instead.
@@ -12,21 +12,21 @@ | |||
"resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", | |||
"integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", | |||
"requires": { | |||
"iconv-lite": "~0.4.13" | |||
"iconv-lite": "0.4.19" |
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.
Based on these lines, it appears you're using an older version of npm. Update to npm@6.4.0 and re-run these installs. That should cut down on the number of changes here.
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.
Ah, I was wondering what was going on here. I tried both 8 and 9, but didn't go to 10. 👍
packages/react-router/package.json
Outdated
@@ -41,6 +41,7 @@ | |||
"history": "^4.7.2", | |||
"hoist-non-react-statics": "^2.5.0", | |||
"invariant": "^2.2.4", | |||
"lodash.isequal": "^4.5.0", |
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.
Can we use something else to achieve this? This adds a fair number of bytes to the bundle, so I'd like to avoid outside dependencies where we can.
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.
Sure -- I only used it to compare match
here (if that link doesn't work, it's in Route.js
line 109)
Do you have any other suggestions of how to compare match
?
Changed location of staticrouter's warning
…static context or not.
@timdorr updated, though I'm curious to see if you think this is a good solution to the problem or not. |
this.setState({ | ||
match: this.computeMatch(nextProps, nextContext.router) | ||
}); | ||
const newMatch = this.computeMatch(this.props, this.context.router); |
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 really like re-computing the match
in the commit phase; this would spend a render phase rendering based on the outdated state.match
just to throw away that work and re-render using the real match.
If it wasn't for the getChildContext()
to support legacy context
, I would probably just compute the match
in render()
(maybe looking into memoizing computing matches). This is probably a decent use case for getDerivedStateFromProps()
, but would break apps apps that use pre-16.3
version of React (or is there a way to backport gDSFP
?).
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.
There's react-lifecycles-compat
, but it's rather large.
We've found most folks are on 16.3+ over on React Redux, FWIW.
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.
Yeah, to my understanding, this is probably the best way to do things without a breaking change (and without including lifecycles-compat).
I'm open to ideas though!
@timdorr just checking in to see if there's anything else preventing this from merging? |
Michael let me know he's planning on giving Router his full attention over the coming week, so I expect it will make its way in somehow! |
Thanks for the PR, @frehner :) I did some major refactoring over the past week and eliminated all the deprecated My apologies for not guiding you through this work so we could get this merged, but it was a little tricky and I wanted to make sure I understood all of the implications of making this change, so I decided to do it myself. You can expect this to be published in our next beta release sometime this week. 😅 |
No worries, just glad to see it done! Thanks! |
Removed all instances of
componentWillMount
andcomponentWillReceiveProps
For the most part, cWM was changed to cDM, except in cases where a parent's function needed to be run before a child's, so those were moved into the constructor. (see
Router.js
as an example).cWRP was replaced with componentDidUpdate. In one case where infinite loops could happen, I added an equality check to stop that. (see
Route.js
).Updated all documentation and examples to remove the old lifecycles and use their supported counterparts.
It appears that I'm the first person to change many of these files after the addition of prettier as a git hook. Many changes, such as adding
;
and changing single to double quotes"
, appear to be a result of that.Tests all pass. I linked this updated code to one of my projects and it appears to all work the same as before, but I only use pretty basic RR-dom components and it's not exhaustive.
Hopefully resolves #6060 and is a more robust version of #6256