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

Add component stack info to key validation warnings #6799

Merged
merged 9 commits into from
May 20, 2016

Conversation

keyz
Copy link
Contributor

@keyz keyz commented May 18, 2016

This PR implements #6790. I rewrote some of the tests from JSX to createElement calls since #6398 added source locations at JSX compile-time and hard-coding line numbers in tests doesn't sound good.

  • "Encountered two children with the same key" error
    • ReactChildReconciler
    • flattenChildren
  • "Each child in an array or iterator should have a unique 'key' prop"
    • ReactElementValidator
  • Switch tests back to JSX and normalize code location info in tests
    • ReactElementValidator-test
    • ReactChildReconciler-test
    • ReactMultiChild-test
  • Clean up ReactElementValidator
    • Update ReactElementValidator-test
  • Fix ReactChildReconciler
  • Refactor flattenChildren and add test cases
    • Test cases
  • Implement ReactComponentTreeDevtool.getStackAddendumByID
  • Pass debugID to ReactTransitionChildMapping.getChildMapping
  • Improve ReactElementValidator Error Message -- Add both child and parent name to key-missing warning stack #6823

addenda.parentOrOwner || '',
addenda.childOwner || '',
addenda.url || ''
addenda.url || '',
Copy link
Collaborator

Choose a reason for hiding this comment

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

We shouldn't need these other addenda now since the stack should cover it. Can you remove the code for them? We still will want to dedupe the warnings based on owner though as we're currently doing.

@facebook-github-bot
Copy link

@keyanzhang updated the pull request.

if (__DEV__) {
traverseAllChildren(
nestedChildNodes,
(childInsts, child, name) => instantiateChild(
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I tried to put selfDebugID as the first arg of instantiateChild and to use instantiateChild.bind(null, selfDebugID) here, but that means we need to call bind as well in the production build. Do you think the current approach (arrowed currying, if that's a term) is acceptable? @spicyj

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yeah, this seems fine to me. (I think calling it parentDebugID might be a little clearer, but this is also oaky.)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmm, I thought about this; self is more clear to me since we are talking about the current component which happens to be the parent for the children here.

@keyz keyz changed the title Added component stack info to key validation warnings Add component stack info to key validation warnings May 19, 2016
@ghost
Copy link

ghost commented May 19, 2016

@keyanzhang updated the pull request.

@ghost
Copy link

ghost commented May 19, 2016

@keyanzhang updated the pull request.

@@ -25,6 +25,9 @@ var ReactTransitionChildMapping = {
if (!children) {
return children;
}
// TODO: `flattenChildren` now takes an extra `selfDebugID` argument
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@spicyj what's a good way to get and feed debugID to flattenChildren here? The only place that calls ReactTransitionChildMapping.getChildMapping (syntactic sugar for flattenChildren) is here: https://github.com/facebook/react/blob/master/src/addons/transitions/ReactTransitionGroup.js#L41. In other words, how do I/can I get a debugID from a component?

Copy link
Contributor Author

@keyz keyz May 19, 2016

Choose a reason for hiding this comment

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

Also, seems like the only other place we use flattenChildren is in ReactMultiChild and there's already a test for that in ReactMultiChild-test. Interestingly, when ReactChildReconciler finds duplicated keys, the error message talks about "flattenChildren" (which is also test covered in the new ReactChildReconciler-test file).

Copy link
Collaborator

Choose a reason for hiding this comment

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

var internalInstance = ReactInstanceMap.get(this);
internalInstance._debugID

should work. Maybe someday we'll have a public API to get this that anyone could use but for now I think it's okay for us to get the internal instance for this here.

@keyz keyz changed the title Add component stack info to key validation warnings [WIP] Add component stack info to key validation warnings May 19, 2016
@keyz keyz changed the title [WIP] Add component stack info to key validation warnings Add component stack info to key validation warnings May 20, 2016
@keyz
Copy link
Contributor Author

keyz commented May 20, 2016

This PR should be ready for review. I refactored ReactElementValidator (inlined a function) but didn't change the warning message since the current message format is more explicit than the component stack info. Please feel free to let me know if you want me to change it. Thanks @spicyj!

@ghost
Copy link

ghost commented May 20, 2016

@keyanzhang updated the pull request.

1 similar comment
@ghost
Copy link

ghost commented May 20, 2016

@keyanzhang updated the pull request.

@@ -192,11 +192,17 @@ var ReactComponentTreeDevtool = {

var currentOwner = ReactCurrentOwner.current;
var id = currentOwner && currentOwner._debugID;

info += ReactComponentTreeDevtool.getStackAddendumByID(id);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nice.

@sophiebits
Copy link
Collaborator

Did you change anything in ReactElementValidator other than adding the stack? It's hard to tell because the code moved around.

@sophiebits
Copy link
Collaborator

(Also, pretty sure I meant to do needs-revision on this last time! Just a few more questions and I think we'll be good.)

@ghost
Copy link

ghost commented May 20, 2016

@keyanzhang updated the pull request.

@@ -38,6 +39,7 @@ var ReactTransitionGroup = React.createClass({

getInitialState: function() {
return {
// TODO: can we get useful debug information to show at this point?
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Interestingly, ReactInstanceMap doesn't have information for the component at this point. That's probably because the component hasn't been mounted.

@sophiebits
Copy link
Collaborator

looks good to me, feel free to "squash and merge"

@keyz keyz merged commit 47e49ae into facebook:master May 20, 2016
@keyz keyz deleted the key-warnings-with-component-stack branch May 20, 2016 23:26
@sophiebits sophiebits added this to the 15.y.z milestone May 22, 2016
@tnrich
Copy link

tnrich commented May 28, 2016

Yay I am so stoked for this to be merged in! Great work react team!

zpao pushed a commit to zpao/react that referenced this pull request Jun 8, 2016
* Add component stack info to key validation warnings

* Add `ReactComponentTreeDevtool.getStackAddendumByID`
(cherry picked from commit 47e49ae)
zpao pushed a commit that referenced this pull request Jun 14, 2016
* Add component stack info to key validation warnings

* Add `ReactComponentTreeDevtool.getStackAddendumByID`
(cherry picked from commit 47e49ae)
@zpao zpao modified the milestones: 15-next, 15.2.0 Jun 14, 2016
troydemonbreun referenced this pull request Jul 5, 2016
(cherry picked from commit 74c29b3 and  bc1d59e)
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