mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
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).
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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(<textarea>giraffe</textarea>);
|
||||
|
||||
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(<textarea>monkey</textarea>);
|
||||
|
||||
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(<textarea>17</textarea>);
|
||||
|
||||
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(<textarea content="purple" />);
|
||||
|
||||
expect(stub.getDOMNode().value).toEqual('purple');
|
||||
stub.receiveProps({ content: 'eggplant' }, transaction);
|
||||
stub.replaceProps({ content: 'eggplant' });
|
||||
expect(stub.getDOMNode().value).toEqual('eggplant');
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user