Add warning when reading from event which has been returned to the pool - #5940
Conversation
|
Rather than throw, I think it should generate a warning. |
|
I think these lines might be relevant: https://github.com/facebook/react/blob/9c3f595597f167fef9b0679f716216bb56e25a14/src/renderers/dom/client/syntheticEvents/SyntheticEvent.js#L160-L162 |
Ah, yes, that's right. Thanks for the reference 👍 |
cc49323 to
024c001
Compare
|
@kentcdodds updated the pull request. |
|
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 |
|
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 |
024c001 to
e808985
Compare
|
Updated. This is technically working, but there are some potential issues that I'll add some inline comments about. |
There was a problem hiding this comment.
When calling preventDefault, we set the defaultPrevented access the nativeEvent properties. This leads to three warnings even if the developer only called preventDefault.
|
On possible suggestion is to set a property on the event called |
|
@kentcdodds updated the pull request. |
|
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 |
|
I think the problem is that when we restore an event, we need to re- Let me know if that sounds wrong. I'll push what I've got so far for review and keep working on it |
e808985 to
2c688f2
Compare
|
@kentcdodds updated the pull request. |
2c688f2 to
fa5582e
Compare
|
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. 👍 |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Perhaps you're supposed to use %s there. Check out other warnings in the codebase.
There was a problem hiding this comment.
I'd add a note about persist() just before the link so the user doesn't overlook the solution they likely need.
|
@kentcdodds updated the pull request. |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Thanks for the reminder. Forgot about that. I totally agree.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 :-)
There was a problem hiding this comment.
Ah, good point. Maybe something like "accessing a method" is neutral enough?
There was a problem hiding this comment.
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.
- Kent C. Dodds https://twitter.com/kentcdodds
|
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 |
105c774 to
69770b3
Compare
|
@kentcdodds updated the pull request. |
69770b3 to
113facd
Compare
|
@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) |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
That make sense. I felt odd spying on it and not asserting anything. Will do.
|
@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. |
|
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! |
|
@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: A test would probably look something like this: |
113facd to
cf76b1c
Compare
|
@kentcdodds updated the pull request. |
|
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 |
|
@kentcdodds This all looks good to me, thanks! But it looks like we broke lint (you can run locally with |
…leased syntheticEvents Closes react#5939
cf76b1c to
6312852
Compare
|
(-‸ლ) thanks! The PR has been updated to fix linting. Looking forward to my next opportunity to contribute ⭐ |
|
@kentcdodds updated the pull request. |
Add warning when reading from event which has been returned to the pool
|
Thanks @kentcdodds! |
|
🎉 🎊 |
Add warning when reading from event which has been returned to the pool
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_ENVfor doing this only in development mode.Thank you for helping a newbie to the codebase :-)