-
Notifications
You must be signed in to change notification settings - Fork 46.9k
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
Warns when mutated props are passed. #5346
Conversation
@@ -147,6 +147,7 @@ var ReactCompositeComponentMixin = { | |||
// Initialize the public class | |||
var inst; | |||
var renderedElement; | |||
var propsMuted = false; |
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.
did you mean mutated?
17104f0
to
ef6aa1e
Compare
@prometheansacrifice updated the pull request. |
ef6aa1e
to
45a49a0
Compare
@jimfb Good enough? |
if (propsMutated) { | ||
warning( | ||
propsMutated, | ||
'Mutated props not allowed in %s(...)', |
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.
If someone is debugging, just saying "Mutated props not allowed in..." doesn't really describe what's wrong. Someone who is writing a moderately complex component might not see what the issue is.
I would say something like "Constructor (of %s) may not invoke super(...)
with props that differ from the props that were initially passed in from the component's owner."
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.
Agreed.
Also, are you sure this works? I thought we set |
45a49a0
to
b05ffdd
Compare
@jimfb Warning does show for the component. However, it is also triggered for another component What is |
@prometheansacrifice TopLevelWrapper is created at the top/root of each render tree. It is a temporary (?) hack so that we can store all top-level pending updates on composites instead of having to worry about different types of components. I'm a little surprised that TopLevelWrapper warns, since I wouldn't expect it to be doing anything fancy with props. The entire definition (in ReactMount.js) is literally only a few lines:
Anyway, we should fix so it doesn't warn for TopLevelWrapper. |
@prometheansacrifice updated the pull request. |
Let's also not warn if you pass up undefined (e.g., |
return <span />; | ||
}; | ||
|
||
function Bar (props) { |
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.
Do you need Foo at all? Why can't Bar extend React.Component directly?
Also, can you use ES6 class syntax here? It's simpler.
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. Foo (or Bar) can directly inherit. Making the change in the next commit.
Is ES6 necessary here? I find most of the React Component definition is ES5 syntax. Simpler as it maybe, mixing up the syntax looks bad on the file as a whole.
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.
We're slowly transitioning to ES6. You'll notice that ES6 syntaxes have been appearing in the docs too; most of the new stuff uses ES6.
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.
Alright then.
@jimfb Is the behaviour correct in the first place? Is it okay for |
TopLevelWrapper doesn't call super at all (which is allowed). Look at its definition in ReactMount. You should not ignore it with a check for its displayName. |
b05ffdd
to
04e9539
Compare
@prometheansacrifice updated the pull request. |
04e9539
to
8a9b3df
Compare
@prometheansacrifice updated the pull request. |
8a9b3df
to
7a86969
Compare
@spicyj Added the fix. Can you please review once again? |
@prometheansacrifice updated the pull request. |
@@ -195,6 +196,18 @@ var ReactCompositeComponentMixin = { | |||
Component.displayName || Component.name || 'Component' | |||
); | |||
} | |||
|
|||
var propsMutated = !shallowEqual(inst.props || {}, publicProps); |
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 must use ===, not shallowEqual.
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.
By ===, you mean deep comparison of objects? I remember @jimfb asking me to avoid as it is expensive.
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.
===
just checks if they are the same reference; it is less expensive than shallowEqual
.
7a86969
to
593a234
Compare
@prometheansacrifice updated the pull request. |
@prometheansacrifice Sorry for the delay. This seems good – thank you. |
Warns when mutated props are passed.
@spicyj Thank you too :) |
Attempts for fix #5335