(this._nestedDOMNode = node)} />
+
+ This should synchronize in both direction with the one above.
+
);
diff --git a/src/renderers/dom/shared/eventPlugins/ChangeEventPlugin.js b/src/renderers/dom/shared/eventPlugins/ChangeEventPlugin.js
index 6381eb54ed..ba1d7b0461 100644
--- a/src/renderers/dom/shared/eventPlugins/ChangeEventPlugin.js
+++ b/src/renderers/dom/shared/eventPlugins/ChangeEventPlugin.js
@@ -47,16 +47,21 @@ function shouldUseChangeEvent(elem) {
);
}
-function createAndAccumulateChangeEvent(inst, nativeEvent, target) {
+function createAndAccumulateChangeEvent(
+ inst,
+ nativeEvent,
+ nativeEventTarget,
+ virtualTarget,
+) {
var event = SyntheticEvent.getPooled(
eventTypes.change,
inst,
nativeEvent,
- target,
+ nativeEventTarget,
);
event.type = 'change';
// Flag this event loop as needing state restore.
- ReactControlledComponent.enqueueStateRestore(target);
+ ReactControlledComponent.enqueueStateRestore(virtualTarget);
EventPropagators.accumulateTwoPhaseDispatches(event);
return event;
}
@@ -175,6 +180,7 @@ var ChangeEventPlugin = {
inst,
nativeEvent,
nativeEventTarget,
+ targetNode,
);
return event;
}
diff --git a/src/renderers/dom/shared/wrappers/__tests__/ReactDOMSelect-test.js b/src/renderers/dom/shared/wrappers/__tests__/ReactDOMSelect-test.js
index 5aa28eff34..95c547b7b9 100644
--- a/src/renderers/dom/shared/wrappers/__tests__/ReactDOMSelect-test.js
+++ b/src/renderers/dom/shared/wrappers/__tests__/ReactDOMSelect-test.js
@@ -589,4 +589,68 @@ describe('ReactDOMSelect', () => {
expect(node.options[1].selected).toBe(true); // b
expect(node.options[2].selected).toBe(false); // c
});
+
+ it('should allow controlling `value` in a nested render', () => {
+ var selectNode;
+
+ class Parent extends React.Component {
+ state = {
+ value: 'giraffe',
+ };
+
+ componentDidMount() {
+ this._renderNested();
+ }
+
+ componentDidUpdate() {
+ this._renderNested();
+ }
+
+ _handleChange(event) {
+ this.setState({value: event.target.value});
+ }
+
+ _renderNested() {
+ ReactDOM.render(
+
,
+ this._nestingContainer,
+ );
+ }
+
+ render() {
+ return
(this._nestingContainer = n)} />;
+ }
+ }
+
+ var container = document.createElement('div');
+
+ document.body.appendChild(container);
+
+ ReactDOM.render(
, container);
+
+ expect(selectNode.value).toBe('giraffe');
+
+ selectNode.value = 'gorilla';
+
+ let nativeEvent = document.createEvent('Event');
+ nativeEvent.initEvent('input', true, true);
+ selectNode.dispatchEvent(nativeEvent);
+
+ expect(selectNode.value).toEqual('gorilla');
+
+ nativeEvent = document.createEvent('Event');
+ nativeEvent.initEvent('change', true, true);
+ selectNode.dispatchEvent(nativeEvent);
+
+ expect(selectNode.value).toEqual('gorilla');
+
+ document.body.removeChild(container);
+ });
});