Skip to content

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

Closed
wants to merge 9 commits into from
Closed

Deprecated lifecycles #6341

wants to merge 9 commits into from

Conversation

frehner
Copy link
Contributor

@frehner frehner commented Sep 18, 2018

Removed all instances of componentWillMount and componentWillReceiveProps

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

Anthony Frehner added 4 commits September 18, 2018 09:56
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(() => {
Copy link
Member

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.

Copy link
Contributor Author

@frehner frehner Sep 19, 2018

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?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

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() {
Copy link
Member

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"
Copy link
Member

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.

Copy link
Contributor Author

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. 👍

@@ -41,6 +41,7 @@
"history": "^4.7.2",
"hoist-non-react-statics": "^2.5.0",
"invariant": "^2.2.4",
"lodash.isequal": "^4.5.0",
Copy link
Member

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.

Copy link
Contributor Author

@frehner frehner Sep 19, 2018

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?

@frehner
Copy link
Contributor Author

frehner commented Sep 19, 2018

@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);
Copy link
Contributor

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?).

Copy link
Member

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.

Copy link
Contributor Author

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!

@frehner
Copy link
Contributor Author

frehner commented Sep 20, 2018

@timdorr just checking in to see if there's anything else preventing this from merging?

@frehner
Copy link
Contributor Author

frehner commented Sep 20, 2018

@timdorr just merged in from your latest work in master (awesome!) and resolved conflicts. Personally, I think it would be great if this could also make the beta mentioned by @mjackson in #5908 (assuming it's ready)

@timdorr
Copy link
Member

timdorr commented Sep 21, 2018

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!

@mjackson
Copy link
Member

Thanks for the PR, @frehner :)

I did some major refactoring over the past week and eliminated all the deprecated componentWill methods in the process, so we won't need this anymore. You can see some of my commits here and here.

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. 😅

@mjackson mjackson closed this Sep 25, 2018
@frehner
Copy link
Contributor Author

frehner commented Sep 25, 2018

No worries, just glad to see it done! Thanks!

@lock lock bot locked as resolved and limited conversation to collaborators Nov 24, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Unsafe Lifecycle warning in React >= 16.3
4 participants