Use latest instance when restoring controlled state (#8443)
Ben Alpert committed
Nov 28, 2016 at 14:00 UTC
f1f07c4a234a4270505228c5f153412a0e716a51
5 files changed
+13
-7
scripts/fiber/tests-failing.txt
-3
@@ -62,9 +62,6 @@ src/renderers/dom/shared/__tests__/ReactRenderDocument-test.js
62
* should throw on full document render w/ no markup
63
* supports findDOMNode on full-page components
64
65
-src/renderers/dom/shared/wrappers/__tests__/ReactDOMInput-test.js
66
-* should control a value in reentrant events
67
-
65
src/renderers/shared/__tests__/ReactPerf-test.js
66
* should count no-op update as waste
67
* should count no-op update in child as waste
scripts/fiber/tests-passing.txt
+1
@@ -859,6 +859,7 @@ src/renderers/dom/shared/wrappers/__tests__/ReactDOMIframe-test.js
859
860
src/renderers/dom/shared/wrappers/__tests__/ReactDOMInput-test.js
861
* should properly control a value even if no event listener exists
862
+* should control a value in reentrant events
863
* should control values in reentrant events with different targets
864
* should display `defaultValue` of number 0
865
* only assigns defaultValue if it changes
src/renderers/dom/shared/eventPlugins/ChangeEventPlugin.js
+1
-1
@@ -52,7 +52,7 @@ function createAndAccumulateChangeEvent(inst, nativeEvent, target) {
52
);
53
event.type = 'change';
54
// Flag this event loop as needing state restore.
55
- ReactControlledComponent.enqueueStateRestore(inst);
55
+ ReactControlledComponent.enqueueStateRestore(target);
56
EventPropagators.accumulateTwoPhaseDispatches(event);
57
return event;
58
}
src/renderers/shared/shared/event/ReactControlledComponent.js
+10
-2
@@ -11,6 +11,8 @@
11
12
'use strict';
13
14
+var EventPluginUtils = require('EventPluginUtils');
15
+
16
var invariant = require('invariant');
17
18
// Use to restore controlled state after a change event has fired.
@@ -28,7 +30,14 @@ var ReactControlledComponentInjection = {
30
var restoreTarget = null;
31
var restoreQueue = null;
32
31
-function restoreStateOfTarget(internalInstance) {
33
+function restoreStateOfTarget(target) {
34
+ // We perform this translation at the end of the event loop so that we
35
+ // always receive the correct fiber here
36
+ var internalInstance = EventPluginUtils.getInstanceFromNode(target);
37
+ if (!internalInstance) {
38
+ // Unmounted
39
+ return;
40
+ }
41
if (typeof internalInstance.tag === 'number') {
42
invariant(
43
fiberHostComponent &&
@@ -36,7 +45,6 @@ function restoreStateOfTarget(internalInstance) {
45
'Fiber needs to be injected to handle a fiber target for controlled ' +
46
'events.'
47
);
39
- // TODO: Ensure that this instance is the current one. Props needs to be correct.
48
fiberHostComponent.restoreControlledState(
49
internalInstance.stateNode,
50
internalInstance.type,
src/test/ReactTestUtils.js
+1
-1
@@ -484,7 +484,7 @@ function makeSimulator(eventType) {
484
ReactGenericBatching.batchedUpdates(function() {
485
// Normally extractEvent enqueues a state restore, but we'll just always
486
// do that since we we're by-passing it here.
487
- ReactControlledComponent.enqueueStateRestore(targetInst);
487
+ ReactControlledComponent.enqueueStateRestore(node);
488
489
EventPluginHub.enqueueEvents(event);
490
EventPluginHub.processEventQueue(true);