-
Notifications
You must be signed in to change notification settings - Fork 47k
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
Release syntheticEvent.target on the destructor #5840
Release syntheticEvent.target on the destructor #5840
Conversation
@@ -500,6 +500,7 @@ function makeSimulator(eventType) { | |||
fakeNativeEvent, | |||
node | |||
); | |||
event.persist(); |
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 seems unrelated?
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.
@syranide
No. Some tests depend on this issue's behavior.
I prefer that the SyntheticEvent
in TestUtils.Simulate
isn't released after the event callback has been invoked.
Should I separate a commit or create an another PR?
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 know enough about testing and how this is used, but if it affects behavior for the event received by the callbacks then this seems wrong.
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 shouldn't do this. It would make Simulate.*
event handlers behave differently than they would in the browser where events aren't automatically persisted (eg a handler calls something with the event in a timeout would end up working in tests but fail in real life).
We should fix that and any other tests, something like this.
var foo = {
onChange = function(e) {
e.persist();
}
}
spyOn(foo, 'onChange').andCallThrough();
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. I removed this line and fixed the failed tests!
This constitutes a potential memory leak, yeah? |
@yaycmyk I don't think it constitutes a memory leak. Persisting the event just means it won't be returned to the synthetic event pool, which should be fine. It will still get garbage collected when all the references are dropped. |
@jimfb I guess I mean if the event target is a node that has been deleted since the event was persisted, the node reference won't be able to be GC'd until it is nulled out or the event is reused as you said. Kind of a leak... |
Persisting is generally an anti-pattern so I'm not too concerned about references there. Regardless, when you call I think the current state of the world without this changes means we have a memory leak (albeit fixed size, so not an exponentially growing leaking) |
@@ -160,6 +160,7 @@ assign(SyntheticEvent.prototype, { | |||
this.dispatchConfig = null; | |||
this._targetInst = null; | |||
this.nativeEvent = null; | |||
this.target = null; |
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 probably want to do this for currentTarget
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.
@zpao I think currentTarget
is already nullifiled because it is in the EventInterface
property.
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.
Ah yea, good call. Really target
should be in that interface too but I get why it's not.
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.
Really target should be in that interface too
I think so. DOM3 Event interface has target
attribute.
SyntheticEvent
has all DOM3 Event interface attributes except target
.
https://www.w3.org/TR/DOM-Level-3-Events/#event-interfaces
Why it's not.
Isn't this enough?
diff --git a/src/renderers/dom/client/syntheticEvents/SyntheticEvent.js b/src/renderers/dom/client/syntheticEvents/SyntheticEvent.js
index f9d0206..48ba4e8 100644
--- a/src/renderers/dom/client/syntheticEvents/SyntheticEvent.js
+++ b/src/renderers/dom/client/syntheticEvents/SyntheticEvent.js
@@ -23,6 +23,7 @@ var warning = require('warning');
*/
var EventInterface = {
type: null,
+ target: null,
// currentTarget is set when dispatching; no use in copying it here
currentTarget: emptyFunction.thatReturnsNull,
eventPhase: null,
@@ -55,16 +56,17 @@ var EventInterface = {
function SyntheticEvent(dispatchConfig, targetInst, nativeEvent, nativeEventTarget) {
this.dispatchConfig = dispatchConfig;
this._targetInst = targetInst;
-
this.nativeEvent = nativeEvent;
- this.target = nativeEventTarget;
- this.currentTarget = nativeEventTarget;
var Interface = this.constructor.Interface;
for (var propName in Interface) {
if (!Interface.hasOwnProperty(propName)) {
continue;
}
+ if (propName === 'target') {
+ this.target = nativeEventTarget;
+ continue;
+ }
var normalize = Interface[propName];
if (normalize) {
this[propName] = normalize(nativeEvent);
@@ -160,7 +162,6 @@ assign(SyntheticEvent.prototype, {
this.dispatchConfig = null;
this._targetInst = null;
this.nativeEvent = null;
- this.target = null;
},
});
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.
Yea, that looks right. Seems like we shouldn't have been setting currentTarget in the c'tor anyway.
I get why it's not
I just meant that it feels awkward to have to check for === 'target'
every time. We could probably move it into the else case below where you have it and then drop the continue.
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.
@zpao Thanks! I updated this.
fbf5159
to
9d2e2c7
Compare
@koba04 updated the pull request. |
9d2e2c7
to
be0551d
Compare
@koba04 updated the pull request. |
Looks great, thanks! |
Release syntheticEvent.target on the destructor
Thanks! |
Currently, SyntheticEvent isn't releasing the
target
property when it calleddestructor
.This PR makes the
target
propertynull
.Please refer to the following fiddle.
https://jsfiddle.net/koba04/9mdse5h9/