Skip to content

Add warning when reading from event which has been returned to the pool - #5940

Merged
jimfb merged 1 commit into
react:masterfrom
kentcdodds:pr/warn-event-pool-access
Feb 18, 2016
Merged

jimfb merged 1 commit into
react:masterfrom
kentcdodds:pr/warn-event-pool-access

Conversation

@kentcdodds

Copy link
Copy Markdown

This is a WIP. I just want to make sure that I'm headed in the right direction for solving #5939

I'm not certain where the logic for deconstructing SyntheticEvents occurs. My guess is it's an abstraction that utilizes the EventInterface.

Also, what's the proper way to reference NODE_ENV for doing this only in development mode.

Thank you for helping a newbie to the codebase :-)

@gaearon

gaearon commented Jan 29, 2016

Copy link
Copy Markdown
Contributor

Rather than throw, I think it should generate a warning.
Here is a another work-in-progress PR you can use as a reference: #5744

@gaearon

gaearon commented Jan 29, 2016

Copy link
Copy Markdown
Contributor

@kentcdodds

Copy link
Copy Markdown
Author

Rather than throw, I think it should generate a warning.

Ah, yes, that's right. Thanks for the reference 👍

@facebook-github-bot

Copy link
Copy Markdown
Contributor

@kentcdodds updated the pull request.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

"property" :)

@zpao

zpao commented Jan 29, 2016

Copy link
Copy Markdown
Contributor

https://github.com/facebook/react/blob/master/src/shared/utils/PooledClass.js#L102-L111 is another place to look. That's what get's run to add pooling to a class, generating a new class with a static release method which calls the destructor (as @gaearon linked to).

@gaearon

gaearon commented Jan 29, 2016

Copy link
Copy Markdown
Contributor

Another thing is you might want to put the warning code into a “devtool” which is a new work-in-progress API for doing dev-only things. See 251d6c3 and #5590 for inspiration.

@zpao

zpao commented Jan 29, 2016

Copy link
Copy Markdown
Contributor

Might be tricky as a "devtool" since you need to add getters, which doesn't fit so well into the devtool event framework (at least as I understand it). Definitely work looking into though

@kentcdodds
kentcdodds force-pushed the pr/warn-event-pool-access branch from 024c001 to e808985 Compare January 29, 2016 20:04
@kentcdodds

Copy link
Copy Markdown
Author

Updated. This is technically working, but there are some potential issues that I'll add some inline comments about.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

When calling preventDefault, we set the defaultPrevented access the nativeEvent properties. This leads to three warnings even if the developer only called preventDefault.

@kentcdodds

Copy link
Copy Markdown
Author

On possible suggestion is to set a property on the event called _nullified or _released and check for that before trying to access any properties.

@facebook-github-bot

Copy link
Copy Markdown
Contributor

@kentcdodds updated the pull request.

@kentcdodds

Copy link
Copy Markdown
Author

Heh... Still got some work on this, I've got quite a few failing tests in the full test suite and some odd behavior in the stopPropogation test (looks like console.error is called 14 times with my warning for some reason).

@kentcdodds

Copy link
Copy Markdown
Author

I think the problem is that when we restore an event, we need to re-defineProperty the object (only in __DEV__) otherwise it will run through my getter/setter and log the warning.

Let me know if that sounds wrong. I'll push what I've got so far for review and keep working on it

@kentcdodds
kentcdodds force-pushed the pr/warn-event-pool-access branch from e808985 to 2c688f2 Compare January 29, 2016 20:19
@facebook-github-bot

Copy link
Copy Markdown
Contributor

@kentcdodds updated the pull request.

@kentcdodds
kentcdodds force-pushed the pr/warn-event-pool-access branch from 2c688f2 to fa5582e Compare January 29, 2016 20:30
@kentcdodds

Copy link
Copy Markdown
Author

Great. I'm ready for feedback now. All tests are passing. I have a linting question I'll add as an inline comment. I'm not solid on this approach, so definitely willing to make changes to how things work or the style of the code. 👍

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I'm getting a linting error:

190:13  error  The second argument to warning must be a string literal  react-internal/warning-and-invariant-args

I think it's because of this line. Is there a reason I can't provide the propName here? I feel like it would be useful to have it.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Perhaps you're supposed to use %s there. Check out other warnings in the codebase.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'd add a note about persist() just before the link so the user doesn't overlook the solution they likely need.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

👍

@facebook-github-bot

Copy link
Copy Markdown
Contributor

@kentcdodds updated the pull request.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

dispatchConfig and _targetInst are both implementation details and are considered private fields.
I think we don't have to warn on accessing those.

This leaves us with nativeEvent which can be hardcoded as a special case below.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

👍

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I still think it's worth adding a sentence about persist() just before the link. If you add it, please do this for every message to keep them consistent.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Thanks for the reminder. Forgot about that. I totally agree.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Also it might be good to hoist the almost identical warning message from getter/setter into the function definition, and pass the different part as %s. In addition, it might be best to preserve the old wording (calling a method rather than accessing the property) for methods.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

In addition, it might be best to preserve the old wording (calling a method rather than accessing the property) for methods.

I considered that, however this wouldn't make sense in a scenario where they're simply getting a reference to the method:

const stop = event.stopPropogation
// maybe use stop later or something?

This would log a warning that wouldn't make sense because they're not actually calling it. I realize that's an edge case, but thought it would make the code simpler and the messaging more accurate.

Definitely willing to be overruled though :-)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Ah, good point. Maybe something like "accessing a method" is neutral enough?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

That's reasonable. Updating now :-)

On Sat, Jan 30, 2016 at 1:00 PM Dan Abramov notifications@github.com
wrote:

In src/renderers/dom/client/syntheticEvents/SyntheticEvent.js
#5940 (comment):

  •    'This synthetic event is reused for performance reasons. If you\'re ' +
    
  •    'seeing this, you\'re setting property `%s` on a ' +
    
  •    'released/nullified synthetic event. This is effectively a no-op. See ' +
    
  •    'https://fb.me/react-event-pooling for more information.',
    
  •    propName
    
  •  );
    
  •  return val;
    
  • },
  • get: function() {
  •  var warningCondition = false;
    
  •  warning(
    
  •    warningCondition,
    
  •    'This synthetic event is reused for performance reasons. If you\'re ' +
    
  •    'seeing this, you\'re accessing property `%s` on a ' +
    
  •    'released/nullified synthetic event. This is %s. See ' +
    
  •    'https://fb.me/react-event-pooling for more information.',
    

Ah, good point. Maybe something like "accessing a method" is neutral
enough?


Reply to this email directly or view it on GitHub
https://github.com/facebook/react/pull/5940/files#r51350027.

@gaearon

gaearon commented Jan 30, 2016

Copy link
Copy Markdown
Contributor

At this point I’ve given all feedback I could give, and what I see so far looks good, apart from minor nits above. Let’s wait for the maintainers to give their further comments. Thank you for contributing!

cc @jimfb

@kentcdodds
kentcdodds force-pushed the pr/warn-event-pool-access branch from 105c774 to 69770b3 Compare January 30, 2016 19:58
@facebook-github-bot

Copy link
Copy Markdown
Contributor

@kentcdodds updated the pull request.

@kentcdodds
kentcdodds force-pushed the pr/warn-event-pool-access branch from 69770b3 to 113facd Compare January 30, 2016 20:06
@facebook-github-bot

Copy link
Copy Markdown
Contributor

@kentcdodds updated the pull request.

});

it('should be nullified if the synthetic event has called destructor', function() {
spyOn(console, 'error'); // accessing properties on destructored events logs warnings (tested elsewhere)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We should still assert the warnings here. The reason being that we want to know if we start emitting some unexpected warnings. Right now, this test just swallows all warnings.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

That make sense. I felt odd spying on it and not asserting anything. Will do.

@jimfb

jimfb commented Feb 11, 2016

Copy link
Copy Markdown
Contributor

@kentcdodds Overall, this looks great to me. A couple of nitpicks. Also, I think it would be good to add an "integration" test (ie. render a component, simulate a click event, save the event, read from the event at the end of the test, and assert the warning fires). Just to sanity check that things are working.

Otherwise, I think we're good to merge.

@kentcdodds

Copy link
Copy Markdown
Author

Happy to write the integration test. I haven't looked into how to do that yet, but I'd appreciate it if you could point me in the right direction to do that :-) Thanks for the feedback!

@jimfb

jimfb commented Feb 11, 2016

Copy link
Copy Markdown
Contributor

@kentcdodds A reasonable example is in ReactServerRendering-test.js, we have a test called "should have the correct mounting behavior". Specifically, the most interesting line is: ReactTestUtils.Simulate.click(ReactDOM.findDOMNode(instance.refs.span));

A test would probably look something like this:

var event = null;
var instance = ReactDOM.render(<div onClick={function(e){event = e;}} />);
ReactTestUtils.Simulate.click(ReactDOM.findDOMNode(instance));`
// TODO: assert warnings.length===0
event.nativeEvent;
// TODO: assert warnings.length===1
// TODO: assert warnings[0].contanis("error message text");

@kentcdodds
kentcdodds force-pushed the pr/warn-event-pool-access branch from 113facd to cf76b1c Compare February 16, 2016 22:21
@facebook-github-bot

Copy link
Copy Markdown
Contributor

@kentcdodds updated the pull request.

@kentcdodds

Copy link
Copy Markdown
Author

Hi @jimfb. Sorry this took a bit. I've updated the tests and added an integration test as you suggested. I think it's solid. One thing that I did change in response to your comments is I combined two tests. When I asserted the console output in the one test, I realized that it was pretty much identical to another. So I just merged the two into one. Let me know if you'd like to see that change.

Thanks for this opportunity to contribute! :D

@jimfb

jimfb commented Feb 18, 2016

Copy link
Copy Markdown
Contributor

@kentcdodds This all looks good to me, thanks! But it looks like we broke lint (you can run locally with npm run lint or view the output here: https://travis-ci.org/facebook/react/jobs/109724188). Just fix the lint errors and do a "git commit --amend", and we should be good to go.

@jimfb jimfb added this to the 0.15 milestone Feb 18, 2016
@jimfb jimfb self-assigned this Feb 18, 2016
@kentcdodds
kentcdodds force-pushed the pr/warn-event-pool-access branch from cf76b1c to 6312852 Compare February 18, 2016 05:46
@kentcdodds

Copy link
Copy Markdown
Author

(-‸ლ) thanks! The PR has been updated to fix linting.

Looking forward to my next opportunity to contribute ⭐

@facebook-github-bot

Copy link
Copy Markdown
Contributor

@kentcdodds updated the pull request.

jimfb added a commit that referenced this pull request Feb 18, 2016
Add warning when reading from event which has been returned to the pool
@jimfb
jimfb merged commit e8e56e8 into react:master Feb 18, 2016
@jimfb

jimfb commented Feb 18, 2016

Copy link
Copy Markdown
Contributor

Thanks @kentcdodds!

@kentcdodds

Copy link
Copy Markdown
Author

🎉 🎊

@kentcdodds
kentcdodds deleted the pr/warn-event-pool-access branch February 18, 2016 06:14
mrizwanashiq pushed a commit to mrizwanashiq/react that referenced this pull request Jun 25, 2026
Add warning when reading from event which has been returned to the pool
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