-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
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
Adjusted no-deprecated rule for React 16.3.0 #1750
Conversation
Added warnings for componentWillMount, componentWillReceiveProps, componentWillUpdate
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.
Thanks, this looks great!
lib/rules/no-deprecated.js
Outdated
@@ -73,6 +76,10 @@ module.exports = { | |||
deprecated[`${pragma}.PropTypes`] = ['15.5.0', 'the npm module prop-types']; | |||
// 15.6.0 | |||
deprecated[`${pragma}.DOM`] = ['15.6.0', 'the npm module react-dom-factories']; | |||
// 16.3.0 | |||
deprecated.componentWillMount = ['16.3.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 supply messages in all these three, that ideally suggest replacements and link to the react docs on the deprecation?
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.
Could you take a look at the new message pattern?
@@ -37,7 +40,7 @@ module.exports = { | |||
schema: [] | |||
}, | |||
|
|||
create: function(context) { | |||
create: Components.detect((context, components, utils) => { |
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.
good change
tests/lib/rules/no-deprecated.js
Outdated
{ | ||
code: 'React.DOM.div', | ||
errors: [{ | ||
message: 'React.DOM is deprecated since React 15.6.0, use the npm module react-dom-factories instead' |
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 all these tests be migrated to use the errorMessage
helper as well?
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 thing, see the updated tests
lib/rules/no-deprecated.js
Outdated
// 16.3.0 | ||
deprecated.componentWillMount = [ | ||
'16.3.0', | ||
'constructor', |
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.
hmm, i'm actually not comfortable recommending the constructor here - side-effecting things should never go in a constructor, and there's still some use cases for componentWillMount
that aren't covered by "constructor" or "getDerivedStateFromProps".
I wonder if maybe we should also add an "ignore" array of method names; ie so I can configure the rule to ignore componentWillMount
but warn on the rest.
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.
How about recommending componentDidMount()
(or UNSAFE_componentWillMount()
as a temporary measure)?
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 guess the unsafe one; but it'd still probably be a good idea to add an ignore list.
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.
So for the sake of consistency this PR should deprecate the 3 life-cycle methods in favor of their UNSAFE_*
counterparts and a future PR should deprecate the unsafe methods completely (after React 17)? Correct?
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.
Agree, in terms of consistency it would be better to deprecated them in favor of UNSAFE_
methods, it should allow to avoid confusion. @ljharb, does it sound reasonable to leave warnings with UNSAFE_
methods as new methods for now and deprecate them in 17.0.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.
Regarding the ignore list for that rule, I vote for adding a dedicated issue for further discussion. I could take a look at it.
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.
A separate issue for the "UNSAFE_" methods would be ideal.
…thods in favor of `UNSAFE_*`
@ljharb, is there anything else that we have to discuss 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.
Thanks, this looks great - I'll rebase and fixup my formatting nits prior to merging.
lib/rules/no-deprecated.js
Outdated
const reactModuleName = getReactModuleName(node); | ||
const isRequire = node.init && node.init.callee && node.init.callee.name === 'require'; | ||
const isReactRequire = | ||
node.init && node.init.arguments && | ||
node.init.arguments.length && typeof MODULES[node.init.arguments[0].value] !== 'undefined' | ||
; | ||
; |
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.
this line should be de-indented
lib/rules/no-deprecated.js
Outdated
// -------------------------------------------------------------------------- | ||
// Public | ||
// -------------------------------------------------------------------------- | ||
|
||
return { | ||
|
||
MemberExpression: function(node) { | ||
MemberExpression: function (node) { |
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.
please revert all unrelated formatting changes in this PR
lib/rules/no-deprecated.js
Outdated
'https://reactjs.org/docs/react-component.html#unsafe_componentwillmount' | ||
]; | ||
deprecated.componentWillReceiveProps = [ | ||
'16.3.0', | ||
'getDerivedStateFromProps', | ||
'UNSAFE_componentWillReceiveProps', |
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.
Why not suggest getDerivedStateFromProps? And why not lint against UNSAFE_ lifecycle methods?
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.
Because that's only one of the use cases for componentWillReceiveProps
, so it's not always the right recommendation.
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's the point of linting against componentWillReceiveProps
if we're just going to recommend UNSAFE_componentWillReceiveProps
anyway? Both are equally bad, no? They do the exact same thing, just one has a scary name.
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.
So that a human can look at it and make a human judgement about which to use.
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 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 think that no-deprecated
can and will warn against them, but not until every use case of them has a replacement (this is not currently the case).
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're no deprecation warnings regarding using UNSAFE_
methods in strict mode, there is unsafe lifecycle methods warning:
So I'm not sure that no-deprecated
is appropriate place for that (at least for now).
I'm also not sure regarding strict-mode
rule, I vote for adding no-unsafe
rule that will be more specific. In the same way that it was done for no-string-refs
rule -- using string ref API also cause warnings in strict mode. @ljharb, I could take a look at it if you find it reasonable.
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.
Modes are not a conceptual pattern I'd want to encourage, "strict" or otherwise.
I don't think a "no-unsafe" rule makes sense when for users of React < 16, it is perfectly safe, and for users of React >= 17, the methods won't work at all.
The purpose of these deprecations from React is to encourage people to migrate to replacements as early as possible, so the breaking change in v17 that removes the old ones will be as painless as possible. When React 17 comes out, we'll certainly lint against invalid lifecycle methods, including newly-invalid ones - but I'm not sure how much value we'd get out of warnings in React 16 outside of no-deprecated
.
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 think a "no-unsafe" rule makes sense when for users of React < 16, it is perfectly safe, and for users of React >= 17, the methods won't work at all.
It's not true, even in version 17, it will still be possible to use UNSAFE_ methods, see Component Lifecycle Changes.
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.
In that case, a separate "no-unsafe" rule, that only focuses on UNSAFE_ methods, seems reasonable.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Another option would be for Additionally, there should probably be a
Not sure what you mean about seeing them in production. React warnings are DEV-only. You'd see them during development. Their only purpose is to warn about removals in future majors — so their presence also doesn't mean your production code is buggy. Unlike many other rules.
A few reasons. The first is that we coalesce runtime warnings where possible. We can show a single warning for many components. We try to avoid showing the same warning twice (if we do, it's usually a bug). The second is that you only see warnings for code that actually runs while you develop. This may seem like it's bad. (Don't we want to find all issues?) But the all-or-nothing approach often discourages people from doing the migration work. If you see all warnings at once (instead of your little corner of the product) you're less incentivized to fix them. So we consider limiting your initial exposure to just the parts you interact with to be a feature, not a bug. Of course once you fixed them (or at least some of them) you want to avoid regressing. That's where the rule comes it. I think lint rules are helpful for preventing regressions, but aren't the best instrument to get notified about the issues for the first time. At least with the open source tools today that just show you all lint warnings at once.
GH notifications in other repos are too noisy but filing a React issue or pinging in Twitter DM are good ways.
We don't have runtime warnings for these methods in React outside of Strict Mode.
I agree with that for new code. The thing I'm worried about is upgrade path. You bump a preset everybody uses, and suddenly it says you have 500 violations. Even if you're on an older React minor that doesn't consider this feature deprecated yet. I think that's pretty confusing. |
I'm concerned about version 17 in lint configuration, it can confuse... As alternative I'd propose to move it to the existing no-unsafe rule since
Sometimes it's also useful to see the entire scope. If you decide to turn on a new lint rule, you usually expect to see warnings/errors. |
👍 |
🤝 if you don't mind I'll request a code review for PR |
Note: writing the doc page is still on my todo list but I'm going on a vacation soon so maybe I'll come back to this after. |
I think it'd be a bit weird to have a second place to configure a React version - at the very least, it sounds like there's a bunch of deprecations in the rule that are activating at React versions that are lower than they should be - a PR to fix that (even if it hoists the warnings to 16.999) would be appreciated. |
Added warnings for deprecated lifecycle methods:
See details React 16.3.0.