@samitouri / QOS-React-2 / commits / ddc4ffffa0
Fork 0

The library for web and native user interfaces.

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).

Ben Alpert committed Jun 12, 2013 at 19:12 UTC ddc4ffffa06a531becb04f4c30b9dd91c5301c53
2 files changed +18 -9
src/core/ReactDOMTextarea.js
+14 -2
@@ -39,6 +39,16 @@ var getTextContent = function(props) {
39 * we intercept prop changes here to make sure that value is updated.
40 */
41 var ReactDOMTextarea = ReactCompositeComponent.createClass({
42 + getInitialState: function() {
43 + // We keep the original value of content and children here so that
44 + // ReactNativeComponent doesn't update textContent (unnecessary since we
45 + // update value).
46 + return {
47 + initialContent: this.props.content,
48 + initialChildren: this.props.children
49 + };
50 + },
51 +
52 render: function() {
53 invariant(
54 this.props.dangerouslySetInnerHTML == null,
@@ -48,13 +58,15 @@ var ReactDOMTextarea = ReactCompositeComponent.createClass({
58 this.props.children == null || CONTENT_TYPES[typeof this.props.children],
59 'When present, textarea children must be a single string or number.'
60 );
51 - return this.transferPropsTo(textarea(null, this.props.children));
61 + return this.transferPropsTo(textarea({
62 + content: this.state.initialContent
63 + }, this.state.initialChildren));
64 },
65
66 componentDidUpdate: function(prevProps, prevState, rootNode) {
67 var oldContent = getTextContent(prevProps);
68 var newContent = getTextContent(this.props);
57 - if (oldContent !== newContent && rootNode.value !== newContent) {
69 + if (oldContent !== newContent) {
70 rootNode.value = newContent;
71 }
72 }
src/core/__tests__/ReactDOMTextarea-test.js
+4 -7
@@ -27,16 +27,13 @@ describe('ReactDOMTextarea', function() {
27 beforeEach(function() {
28 React = require('React');
29 ReactTestUtils = require('ReactTestUtils');
30 -
31 - var ReactReconcileTransaction = require('ReactReconcileTransaction');
32 - transaction = new ReactReconcileTransaction();
30 });
31
32 it("should remove value with removed children", function() {
33 var stub = ReactTestUtils.renderIntoDocument(<textarea>giraffe</textarea>);
34
35 expect(stub.getDOMNode().value).toEqual('giraffe');
39 - stub.receiveProps({ children: null }, transaction);
36 + stub.replaceProps({ children: null });
37 expect(stub.getDOMNode().value).toEqual('');
38 });
39
@@ -44,7 +41,7 @@ describe('ReactDOMTextarea', function() {
41 var stub = ReactTestUtils.renderIntoDocument(<textarea>monkey</textarea>);
42
43 expect(stub.getDOMNode().value).toEqual('monkey');
47 - stub.receiveProps({ children: 'gorilla' }, transaction);
44 + stub.replaceProps({ children: 'gorilla' });
45 expect(stub.getDOMNode().value).toEqual('gorilla');
46 });
47
@@ -52,7 +49,7 @@ describe('ReactDOMTextarea', function() {
49 var stub = ReactTestUtils.renderIntoDocument(<textarea>17</textarea>);
50
51 expect(stub.getDOMNode().value).toEqual('17');
55 - stub.receiveProps({ children: 289 }, transaction);
52 + stub.replaceProps({ children: 289 });
53 expect(stub.getDOMNode().value).toEqual('289');
54 });
55
@@ -60,7 +57,7 @@ describe('ReactDOMTextarea', function() {
57 var stub = ReactTestUtils.renderIntoDocument(<textarea content="purple" />);
58
59 expect(stub.getDOMNode().value).toEqual('purple');
63 - stub.receiveProps({ content: 'eggplant' }, transaction);
60 + stub.replaceProps({ content: 'eggplant' });
61 expect(stub.getDOMNode().value).toEqual('eggplant');
62 });
63 });