Skip to content
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

Expanded DEV-only warnings for gDSFP and legacy lifecycles #12419

Merged
merged 7 commits into from
Mar 22, 2018

Conversation

bvaughn
Copy link
Contributor

@bvaughn bvaughn commented Mar 21, 2018

After a lot of discussion and careful consideration, the team has reaffirmed the initial decision to not call unsafe legacy lifecycles componentWillMount, componentWillReceiveProps, and componentWillUpdate for any component that defines the new static getDerivedStateFromProps lifecycle. (This applies to the "UNSAFE_" aliases as well.)

The reason for this decision ultimately boils down to support for the react-lifecycles-compat polyfill and concerns about consistent, predictable behavior for future version of React.

As @jquense pointed out with issue #12411, conditional lifecycle behavior is a new thing, and it is not intuitive. For this reason, we needed to improve the granularity and wording of the DEV warning. This PR does that, first by expanding the warning conditionals to explicitly check for componentWillMount and componentWillUpdate as well (rather than just componentWillReceiveProps) and secondly by explicitly stating that "Unsafe legacy lifecycles will not be called for components using the new getDerivedStateFromProps() API".

The entire new DEV warning is:

Unsafe legacy lifecycles will not be called for components using the new 
getDerivedStateFromProps() API.

<YourComponentName> uses getDerivedStateFromProps() but also contains 
the following legacy lifecycles:
  componentWillMount
  componentWillReceiveProps
  componentWillUpdate

The above lifecycles should be removed. Learn more about this warning here:
https://fb.me/react-async-component-lifecycle-hooks

Tests have been updated as well to verify the new behavior.

Resolves #12411

@aweary
Copy link
Contributor

aweary commented Mar 21, 2018

@bvaughn will this also apply to other new lifecycle methods, like getSnapshotBeforeUpdate?

@bvaughn
Copy link
Contributor Author

bvaughn commented Mar 21, 2018

I have no current plans for that to be the case, no.

@bvaughn
Copy link
Contributor Author

bvaughn commented Mar 22, 2018

I've updated the PR description to more clearly reflect the considerations that went into this decision. Please let me know if there are any concerns about vague wording or if I omitted anything.

Copy link
Contributor

@aweary aweary left a comment

Choose a reason for hiding this comment

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

@bvaughn thanks for clarifying! Can you expand on why this same behavior (conditional lifecycles) won't extend to other new lifecycle methods? What is special about gDSFP?

}).toWarnDev('Defines both componentWillReceiveProps');
}).toWarnDev(
'Unsafe legacy lifecycles will not be called for components using the new getDerivedStateFromProps() API.\n\n' +
'Unknown uses getDerivedStateFromProps() but also contains the following legacy lifecycles:\n' +
Copy link
Contributor

Choose a reason for hiding this comment

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

Using "Unknown" as a proper noun feels kind of confusing, but I can't think of something better.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agreed. I wonder if there's a way I could improve this by reformatting the message slightly.

Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe "An unknown component uses..."?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That makes it seem like React doesn't know which component, when really- it just doesn't know what the name fo the component is.

Maybe "An unnamed component" ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Actually I think just plain "Component" might be okay, and more inline with other places.

Copy link
Contributor

Choose a reason for hiding this comment

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

In what cases does React not know the name of a component? "An unnamed component" sounds better than "Unknown" to me 👍

Copy link
Contributor Author

Choose a reason for hiding this comment

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

create-react-class case

@bvaughn
Copy link
Contributor Author

bvaughn commented Mar 22, 2018

@bvaughn thanks for clarifying! Can you expand on why this same behavior (conditional lifecycles) won't extend to other new lifecycle methods? What is special about gDSFP?

The biggest reason is that the react-lifecycles-compat polyfill relies on unsafe legacy lifecycles componentWillMount and componentWillReceiveProps to work. We know there will be shared components that intentionally define both the old and new lifecycles- (via the polyfill)- and double executing that code could be slow and would likely be confusing as well.

A second argument is that, conceptually, it doesn't make sense to combine the new and old portions of the component API (outside of the case of the polyfill). The new API exists as a safe alternative to the old, not as a compliment.

@aweary
Copy link
Contributor

aweary commented Mar 22, 2018

@bvaughn to clarify, I'm asking for clarification on your response to my question:

will this also apply to other new lifecycle methods, like getSnapshotBeforeUpdate?

I understand the argument for prevent users from mixing new and old APIs, but I'm curious why this won't apply to other new lifecycle methods, like getSnapshotBeforeUpdate? It seems like the same argument would apply to any new lifecycles.

@bvaughn
Copy link
Contributor Author

bvaughn commented Mar 22, 2018

Let's move this conversation over to the getSnapshotBeforeUpdate RFC/PR?

As I think more about how I would implement getSnapshotBeforeUpdate support in the polyfill, I think it might make sense to carry this behavior over to that new lifecycle as well. But that's not the focus of this PR. 😄

@bvaughn
Copy link
Contributor Author

bvaughn commented Mar 22, 2018

FYI @aweary, I added a polyfill section to the other RFC.

@toFrankie
Copy link

I have the same problem.

Can getDerivedStateFromProps not be used at the same time with unsafe lifecycle functions such as UNSAFE_componentWillMount?

Warning: Unsafe legacy lifecycles will not be called for components using new component APIs.

LifeCycle uses getDerivedStateFromProps() but also contains the following legacy lifecycles:
  UNSAFE_componentWillMount

The above lifecycles should be removed. Learn more about this warning here:
https://fb.me/react-unsafe-component-lifecycles

When I remove UNSAFE_componentWillMount there will be no warning.

Examples are as follows:

import React, { Component } from 'react'

export default class LifeCycle extends Component {
  constructor(props) {
    super(props)
    this.state = {}
  }

  static getDerivedStateFromProps() {
    return null
  }

  UNSAFE_componentWillMount() {}

  componentDidMount() {}

  render() {
    return (
      <div>React Life Cycle</div>
    )
  }
}

@bvaughn bvaughn deleted the issues/12411 branch July 2, 2021 15:46
@gaearon
Copy link
Collaborator

gaearon commented Jul 2, 2021

Can getDerivedStateFromProps not be used at the same time with unsafe lifecycle functions such as UNSAFE_componentWillMount?

No. That's what the warning says.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants