From ddc4ffffa06a531becb04f4c30b9dd91c5301c53 Mon Sep 17 00:00:00 2001 From: Ben Alpert Date: Wed, 12 Jun 2013 19:12:52 -0700 Subject: [PATCH] Don't let textarea value change via textContent Turns out my tests before weren't particularly useful because receiveProps doesn't end up running componentDidUpdate since the transaction never finishes. Now they use replaceProps instead (and I verified that commenting out the "rootNode.value = ..." line makes the tests fail, which wasn't true before). --- src/core/ReactDOMTextarea.js | 16 ++++++++++++++-- src/core/__tests__/ReactDOMTextarea-test.js | 11 ++++------- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/core/ReactDOMTextarea.js b/src/core/ReactDOMTextarea.js index f7c9eaae30..f484da01cb 100644 --- a/src/core/ReactDOMTextarea.js +++ b/src/core/ReactDOMTextarea.js @@ -39,6 +39,16 @@ var getTextContent = function(props) { * we intercept prop changes here to make sure that value is updated. */ var ReactDOMTextarea = ReactCompositeComponent.createClass({ + getInitialState: function() { + // We keep the original value of content and children here so that + // ReactNativeComponent doesn't update textContent (unnecessary since we + // update value). + return { + initialContent: this.props.content, + initialChildren: this.props.children + }; + }, + render: function() { invariant( this.props.dangerouslySetInnerHTML == null, @@ -48,13 +58,15 @@ var ReactDOMTextarea = ReactCompositeComponent.createClass({ this.props.children == null || CONTENT_TYPES[typeof this.props.children], 'When present, textarea children must be a single string or number.' ); - return this.transferPropsTo(textarea(null, this.props.children)); + return this.transferPropsTo(textarea({ + content: this.state.initialContent + }, this.state.initialChildren)); }, componentDidUpdate: function(prevProps, prevState, rootNode) { var oldContent = getTextContent(prevProps); var newContent = getTextContent(this.props); - if (oldContent !== newContent && rootNode.value !== newContent) { + if (oldContent !== newContent) { rootNode.value = newContent; } } diff --git a/src/core/__tests__/ReactDOMTextarea-test.js b/src/core/__tests__/ReactDOMTextarea-test.js index 00f7bed92d..1fb6d97820 100644 --- a/src/core/__tests__/ReactDOMTextarea-test.js +++ b/src/core/__tests__/ReactDOMTextarea-test.js @@ -27,16 +27,13 @@ describe('ReactDOMTextarea', function() { beforeEach(function() { React = require('React'); ReactTestUtils = require('ReactTestUtils'); - - var ReactReconcileTransaction = require('ReactReconcileTransaction'); - transaction = new ReactReconcileTransaction(); }); it("should remove value with removed children", function() { var stub = ReactTestUtils.renderIntoDocument(); expect(stub.getDOMNode().value).toEqual('giraffe'); - stub.receiveProps({ children: null }, transaction); + stub.replaceProps({ children: null }); expect(stub.getDOMNode().value).toEqual(''); }); @@ -44,7 +41,7 @@ describe('ReactDOMTextarea', function() { var stub = ReactTestUtils.renderIntoDocument(); expect(stub.getDOMNode().value).toEqual('monkey'); - stub.receiveProps({ children: 'gorilla' }, transaction); + stub.replaceProps({ children: 'gorilla' }); expect(stub.getDOMNode().value).toEqual('gorilla'); }); @@ -52,7 +49,7 @@ describe('ReactDOMTextarea', function() { var stub = ReactTestUtils.renderIntoDocument(); expect(stub.getDOMNode().value).toEqual('17'); - stub.receiveProps({ children: 289 }, transaction); + stub.replaceProps({ children: 289 }); expect(stub.getDOMNode().value).toEqual('289'); }); @@ -60,7 +57,7 @@ describe('ReactDOMTextarea', function() { var stub = ReactTestUtils.renderIntoDocument(