From 556065937b91a08635799934bee12259cdb439bd Mon Sep 17 00:00:00 2001 From: Ben Alpert Date: Thu, 26 Dec 2013 23:05:41 -0700 Subject: [PATCH] Make controlled components and bubbling work in IE Fixes #708. Test Plan: In IE9, tested a controlled text input with the event handler on a containing element, as in the fiddle linked in the original issue. Also tested a controlled radio button as the logic there differs within ReactDOMInput. In both cases, I was able to interact with the controls. --- src/eventPlugins/ChangeEventPlugin.js | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/eventPlugins/ChangeEventPlugin.js b/src/eventPlugins/ChangeEventPlugin.js index ad8fa70f120..61a9324d17f 100644 --- a/src/eventPlugins/ChangeEventPlugin.js +++ b/src/eventPlugins/ChangeEventPlugin.js @@ -22,6 +22,7 @@ var EventConstants = require('EventConstants'); var EventPluginHub = require('EventPluginHub'); var EventPropagators = require('EventPropagators'); var ExecutionEnvironment = require('ExecutionEnvironment'); +var ReactUpdates = require('ReactUpdates'); var SyntheticEvent = require('SyntheticEvent'); var isEventSupported = require('isEventSupported'); @@ -73,10 +74,21 @@ function manualDispatchChangeEvent(nativeEvent) { ); EventPropagators.accumulateTwoPhaseDispatches(event); - // If change bubbled, we'd just bind to it like all the other events - // and have it go through ReactEventTopLevelCallback. Since it doesn't, we - // manually listen for the change event and so we have to enqueue and + // If change and propertychange bubbled, we'd just bind to it like all the + // other events and have it go through ReactEventTopLevelCallback. Since it + // doesn't, we manually listen for the events and so we have to enqueue and // process the abstract event manually. + // + // Batching is necessary here in order to ensure that all event handlers run + // before the next rerender (including event handlers attached to ancestor + // elements instead of directly on the input). Without this, controlled + // components don't work properly in conjunction with event bubbling because + // the component is rerendered and the value reverted before all the event + // handlers can run. See https://github.com/facebook/react/issues/708. + ReactUpdates.batchedUpdates(runEventInBatch, event); +} + +function runEventInBatch(event) { EventPluginHub.enqueueEvents(event); EventPluginHub.processEventQueue(); }