mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Warn when accessing .props, .setProps on DOM components
This commit is contained in:
1 parent
ba81b60ad8
commit
bfcad9614a
14 files changed
+324
-151
No files matched your search
@@ -15,45 +15,16 @@ describe('sliceChildren', function() {
|
||||
|
||||
var React;
|
||||
var ReactFragment;
|
||||
var ReactTestUtils;
|
||||
|
||||
var sliceChildren;
|
||||
var reactComponentExpect;
|
||||
|
||||
var Partial;
|
||||
|
||||
beforeEach(function() {
|
||||
React = require('React');
|
||||
ReactFragment = require('ReactFragment');
|
||||
ReactTestUtils = require('ReactTestUtils');
|
||||
|
||||
sliceChildren = require('sliceChildren');
|
||||
reactComponentExpect = require('reactComponentExpect');
|
||||
|
||||
Partial = React.createClass({
|
||||
render: function() {
|
||||
return (
|
||||
<div>
|
||||
{sliceChildren(
|
||||
this.props.children,
|
||||
this.props.start,
|
||||
this.props.end
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
function renderAndSlice(set, start, end) {
|
||||
var instance = <Partial start={start} end={end}>{set}</Partial>;
|
||||
instance = ReactTestUtils.renderIntoDocument(instance);
|
||||
var rendered = reactComponentExpect(instance)
|
||||
.expectRenderedChild()
|
||||
.instance();
|
||||
return rendered.props.children;
|
||||
}
|
||||
|
||||
function testKeyValuePairs(children, expectedPairs) {
|
||||
var obj = ReactFragment.extract(children);
|
||||
expect(obj).toEqual(expectedPairs);
|
||||
@@ -65,7 +36,7 @@ describe('sliceChildren', function() {
|
||||
<div key="B" />,
|
||||
<div key="C" />,
|
||||
];
|
||||
var children = renderAndSlice(fullSet, 0);
|
||||
var children = sliceChildren(fullSet, 0);
|
||||
testKeyValuePairs(children, {
|
||||
'.$A': fullSet[0],
|
||||
'.$B': fullSet[1],
|
||||
@@ -79,7 +50,7 @@ describe('sliceChildren', function() {
|
||||
<div key="B" />,
|
||||
<div key="C" />,
|
||||
];
|
||||
var children = renderAndSlice(fullSet, 1);
|
||||
var children = sliceChildren(fullSet, 1);
|
||||
testKeyValuePairs(children, {
|
||||
'.$B': fullSet[1],
|
||||
'.$C': fullSet[2],
|
||||
@@ -93,7 +64,7 @@ describe('sliceChildren', function() {
|
||||
<div key="C" />,
|
||||
<div key="D" />,
|
||||
];
|
||||
var children = renderAndSlice(fullSet, 1, 2);
|
||||
var children = sliceChildren(fullSet, 1, 2);
|
||||
testKeyValuePairs(children, {
|
||||
'.$B': fullSet[1],
|
||||
});
|
||||
@@ -104,13 +75,9 @@ describe('sliceChildren', function() {
|
||||
var b = <div />;
|
||||
var c = <div />;
|
||||
|
||||
var instance = <Partial start={1} end={2}>{a}{b}{c}</Partial>;
|
||||
instance = ReactTestUtils.renderIntoDocument(instance);
|
||||
var rendered = reactComponentExpect(instance)
|
||||
.expectRenderedChild()
|
||||
.instance();
|
||||
|
||||
testKeyValuePairs(rendered.props.children, {
|
||||
var el = <div>{a}{b}{c}</div>;
|
||||
var children = sliceChildren(el.props.children, 1, 2);
|
||||
testKeyValuePairs(children, {
|
||||
'.1': b,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -79,32 +79,32 @@ describe('ReactDOM', function() {
|
||||
</div>
|
||||
);
|
||||
// Warm the cache with theDog
|
||||
myDiv.setProps({
|
||||
children: [
|
||||
myDiv = ReactTestUtils.renderIntoDocument(
|
||||
<div>
|
||||
<div key="theDog" className="dogbeforedelete" />,
|
||||
<div key="theBird" className="bird" />,
|
||||
],
|
||||
});
|
||||
</div>
|
||||
);
|
||||
// Remove theDog - this should purge the cache
|
||||
myDiv.setProps({
|
||||
children: [
|
||||
myDiv = ReactTestUtils.renderIntoDocument(
|
||||
<div>
|
||||
<div key="theBird" className="bird" />,
|
||||
],
|
||||
});
|
||||
</div>
|
||||
);
|
||||
// Now, put theDog back. It's now a different DOM node.
|
||||
myDiv.setProps({
|
||||
children: [
|
||||
myDiv = ReactTestUtils.renderIntoDocument(
|
||||
<div>
|
||||
<div key="theDog" className="dog" />,
|
||||
<div key="theBird" className="bird" />,
|
||||
],
|
||||
});
|
||||
</div>
|
||||
);
|
||||
// Change the className of theDog. It will use the same element
|
||||
myDiv.setProps({
|
||||
children: [
|
||||
myDiv = ReactTestUtils.renderIntoDocument(
|
||||
<div>
|
||||
<div key="theDog" className="bigdog" />,
|
||||
<div key="theBird" className="bird" />,
|
||||
],
|
||||
});
|
||||
</div>
|
||||
);
|
||||
var root = React.findDOMNode(myDiv);
|
||||
var dog = root.childNodes[0];
|
||||
expect(dog.className).toBe('bigdog');
|
||||
|
||||
@@ -53,27 +53,41 @@ describe('ReactDOMButton', function() {
|
||||
});
|
||||
|
||||
it('should forward clicks when it becomes not disabled', function() {
|
||||
var btn = mounted(<button disabled={true} onClick={onClick} />);
|
||||
btn.setProps({disabled: false});
|
||||
var container = document.createElement('div');
|
||||
var btn = React.render(
|
||||
<button disabled={true} onClick={onClick} />,
|
||||
container
|
||||
);
|
||||
btn = React.render(
|
||||
<button onClick={onClick} />,
|
||||
container
|
||||
);
|
||||
expectClickThru(btn);
|
||||
});
|
||||
|
||||
it('should not forward clicks when it becomes disabled', function() {
|
||||
var btn = mounted(<button onClick={onClick} />);
|
||||
btn.setProps({disabled: true});
|
||||
var container = document.createElement('div');
|
||||
var btn = React.render(
|
||||
<button onClick={onClick} />,
|
||||
container
|
||||
);
|
||||
btn = React.render(
|
||||
<button disabled={true} onClick={onClick} />,
|
||||
container
|
||||
);
|
||||
expectNoClickThru(btn);
|
||||
});
|
||||
|
||||
it('should work correctly if the listener is changed', function() {
|
||||
var btn = mounted(
|
||||
<button disabled={true} onClick={function() {}} />
|
||||
var container = document.createElement('div');
|
||||
var btn = React.render(
|
||||
<button disabled={true} onClick={function() {}} />,
|
||||
container
|
||||
);
|
||||
btn = React.render(
|
||||
<button disabled={false} onClick={onClick} />,
|
||||
container
|
||||
);
|
||||
|
||||
btn.setProps({
|
||||
disabled: false,
|
||||
onClick: onClick,
|
||||
});
|
||||
|
||||
expectClickThru(btn);
|
||||
});
|
||||
});
|
||||
@@ -75,30 +75,39 @@ describe('ReactDOMInput', function() {
|
||||
});
|
||||
|
||||
it('should allow setting `value` to `true`', function() {
|
||||
var container = document.createElement('div');
|
||||
var stub = <input type="text" value="yolo" onChange={emptyFunction} />;
|
||||
stub = ReactTestUtils.renderIntoDocument(stub);
|
||||
stub = React.render(stub, container);
|
||||
var node = React.findDOMNode(stub);
|
||||
|
||||
expect(node.value).toBe('yolo');
|
||||
|
||||
stub.replaceProps({value: true, onChange: emptyFunction});
|
||||
stub = React.render(
|
||||
<input type="text" value={true} onChange={emptyFunction} />,
|
||||
container
|
||||
);
|
||||
expect(node.value).toEqual('true');
|
||||
});
|
||||
|
||||
it('should allow setting `value` to `false`', function() {
|
||||
var container = document.createElement('div');
|
||||
var stub = <input type="text" value="yolo" onChange={emptyFunction} />;
|
||||
stub = ReactTestUtils.renderIntoDocument(stub);
|
||||
stub = React.render(stub, container);
|
||||
var node = React.findDOMNode(stub);
|
||||
|
||||
expect(node.value).toBe('yolo');
|
||||
|
||||
stub.replaceProps({value: false});
|
||||
stub = React.render(
|
||||
<input type="text" value={false} onChange={emptyFunction} />,
|
||||
container
|
||||
);
|
||||
expect(node.value).toEqual('false');
|
||||
});
|
||||
|
||||
it('should allow setting `value` to `objToString`', function() {
|
||||
var container = document.createElement('div');
|
||||
var stub = <input type="text" value="foo" onChange={emptyFunction} />;
|
||||
stub = ReactTestUtils.renderIntoDocument(stub);
|
||||
stub = React.render(stub, container);
|
||||
var node = React.findDOMNode(stub);
|
||||
|
||||
expect(node.value).toBe('foo');
|
||||
@@ -108,8 +117,10 @@ describe('ReactDOMInput', function() {
|
||||
return 'foobar';
|
||||
},
|
||||
};
|
||||
|
||||
stub.replaceProps({value: objToString, onChange: emptyFunction});
|
||||
stub = React.render(
|
||||
<input type="text" value={objToString} onChange={emptyFunction} />,
|
||||
container
|
||||
);
|
||||
expect(node.value).toEqual('foobar');
|
||||
});
|
||||
|
||||
|
||||
@@ -32,13 +32,18 @@ describe('ReactDOMSelect', function() {
|
||||
<option value="giraffe">A giraffe!</option>
|
||||
<option value="gorilla">A gorilla!</option>
|
||||
</select>;
|
||||
stub = ReactTestUtils.renderIntoDocument(stub);
|
||||
var options = stub.props.children;
|
||||
var container = document.createElement('div');
|
||||
stub = React.render(stub, container);
|
||||
var node = React.findDOMNode(stub);
|
||||
|
||||
expect(node.value).toBe('giraffe');
|
||||
|
||||
// Changing `defaultValue` should do nothing.
|
||||
stub.setProps({defaultValue: 'gorilla'});
|
||||
React.render(
|
||||
<select defaultValue="gorilla">{options}</select>,
|
||||
container
|
||||
);
|
||||
expect(node.value).toEqual('giraffe');
|
||||
});
|
||||
|
||||
@@ -51,19 +56,20 @@ describe('ReactDOMSelect', function() {
|
||||
});
|
||||
|
||||
it('should not control when using `defaultValue`', function() {
|
||||
var stub =
|
||||
var el =
|
||||
<select defaultValue="giraffe">
|
||||
<option value="monkey">A monkey!</option>
|
||||
<option value="giraffe">A giraffe!</option>
|
||||
<option value="gorilla">A gorilla!</option>
|
||||
</select>;
|
||||
stub = ReactTestUtils.renderIntoDocument(stub);
|
||||
var container = document.createElement('div');
|
||||
var stub = React.render(el, container);
|
||||
var node = React.findDOMNode(stub);
|
||||
|
||||
expect(node.value).toBe('giraffe');
|
||||
|
||||
node.value = 'monkey';
|
||||
stub.forceUpdate();
|
||||
React.render(el, container);
|
||||
// Uncontrolled selects shouldn't change the value after first mounting
|
||||
expect(node.value).toEqual('monkey');
|
||||
});
|
||||
@@ -75,7 +81,9 @@ describe('ReactDOMSelect', function() {
|
||||
<option value="giraffe">A giraffe!</option>
|
||||
<option value="gorilla">A gorilla!</option>
|
||||
</select>;
|
||||
stub = ReactTestUtils.renderIntoDocument(stub);
|
||||
var options = stub.props.children;
|
||||
var container = document.createElement('div');
|
||||
stub = React.render(stub, container);
|
||||
var node = React.findDOMNode(stub);
|
||||
|
||||
expect(node.options[0].selected).toBe(false); // monkey
|
||||
@@ -83,7 +91,10 @@ describe('ReactDOMSelect', function() {
|
||||
expect(node.options[2].selected).toBe(true); // gorilla
|
||||
|
||||
// Changing `defaultValue` should do nothing.
|
||||
stub.setProps({defaultValue: ['monkey']});
|
||||
React.render(
|
||||
<select multiple={true} defaultValue={['monkey']}>{options}</select>,
|
||||
container
|
||||
);
|
||||
|
||||
expect(node.options[0].selected).toBe(false); // monkey
|
||||
expect(node.options[1].selected).toBe(true); // giraffe
|
||||
@@ -97,13 +108,18 @@ describe('ReactDOMSelect', function() {
|
||||
<option value="giraffe">A giraffe!</option>
|
||||
<option value="gorilla">A gorilla!</option>
|
||||
</select>;
|
||||
stub = ReactTestUtils.renderIntoDocument(stub);
|
||||
var options = stub.props.children;
|
||||
var container = document.createElement('div');
|
||||
stub = React.render(stub, container);
|
||||
var node = React.findDOMNode(stub);
|
||||
|
||||
expect(node.value).toBe('giraffe');
|
||||
|
||||
// Changing the `value` prop should change the selected option.
|
||||
stub.setProps({value: 'gorilla'});
|
||||
React.render(
|
||||
<select value="gorilla">{options}</select>,
|
||||
container
|
||||
);
|
||||
expect(node.value).toEqual('gorilla');
|
||||
});
|
||||
|
||||
@@ -122,7 +138,9 @@ describe('ReactDOMSelect', function() {
|
||||
<option value="giraffe">A giraffe!</option>
|
||||
<option value="gorilla">A gorilla!</option>
|
||||
</select>;
|
||||
stub = ReactTestUtils.renderIntoDocument(stub);
|
||||
var options = stub.props.children;
|
||||
var container = document.createElement('div');
|
||||
stub = React.render(stub, container);
|
||||
var node = React.findDOMNode(stub);
|
||||
|
||||
expect(node.options[0].selected).toBe(false); // monkey
|
||||
@@ -130,7 +148,10 @@ describe('ReactDOMSelect', function() {
|
||||
expect(node.options[2].selected).toBe(true); // gorilla
|
||||
|
||||
// Changing the `value` prop should change the selected options.
|
||||
stub.setProps({value: ['monkey']});
|
||||
React.render(
|
||||
<select multiple={true} value={['monkey']}>{options}</select>,
|
||||
container
|
||||
);
|
||||
|
||||
expect(node.options[0].selected).toBe(true); // monkey
|
||||
expect(node.options[1].selected).toBe(false); // giraffe
|
||||
@@ -154,15 +175,17 @@ describe('ReactDOMSelect', function() {
|
||||
|
||||
it('should reset child options selected when they are changed and `value` is set', function() {
|
||||
var stub = <select multiple={true} value={['a', 'b']} />;
|
||||
stub = ReactTestUtils.renderIntoDocument(stub);
|
||||
var container = document.createElement('div');
|
||||
stub = React.render(stub, container);
|
||||
|
||||
stub.setProps({
|
||||
children: [
|
||||
<option value="a">a</option>,
|
||||
<option value="b">b</option>,
|
||||
<option value="c">c</option>,
|
||||
],
|
||||
});
|
||||
React.render(
|
||||
<select multiple={true} value={['a', 'b']}>
|
||||
<option value="a">a</option>
|
||||
<option value="b">b</option>
|
||||
<option value="c">c</option>
|
||||
</select>,
|
||||
container
|
||||
);
|
||||
|
||||
var node = React.findDOMNode(stub);
|
||||
|
||||
@@ -179,13 +202,14 @@ describe('ReactDOMSelect', function() {
|
||||
},
|
||||
};
|
||||
|
||||
var stub =
|
||||
var el =
|
||||
<select multiple={true} value={[objectToString]}>
|
||||
<option value="monkey">A monkey!</option>
|
||||
<option value="giraffe">A giraffe!</option>
|
||||
<option value="gorilla">A gorilla!</option>
|
||||
</select>;
|
||||
stub = ReactTestUtils.renderIntoDocument(stub);
|
||||
var container = document.createElement('div');
|
||||
var stub = React.render(el, container);
|
||||
var node = React.findDOMNode(stub);
|
||||
|
||||
expect(node.options[0].selected).toBe(false); // monkey
|
||||
@@ -194,7 +218,7 @@ describe('ReactDOMSelect', function() {
|
||||
|
||||
// Changing the `value` prop should change the selected options.
|
||||
objectToString.animal = 'monkey';
|
||||
stub.forceUpdate();
|
||||
React.render(el, container);
|
||||
|
||||
expect(node.options[0].selected).toBe(true); // monkey
|
||||
expect(node.options[1].selected).toBe(false); // giraffe
|
||||
@@ -208,7 +232,9 @@ describe('ReactDOMSelect', function() {
|
||||
<option value="giraffe">A giraffe!</option>
|
||||
<option value="gorilla">A gorilla!</option>
|
||||
</select>;
|
||||
stub = ReactTestUtils.renderIntoDocument(stub);
|
||||
var options = stub.props.children;
|
||||
var container = document.createElement('div');
|
||||
stub = React.render(stub, container);
|
||||
var node = React.findDOMNode(stub);
|
||||
|
||||
expect(node.options[0].selected).toBe(false); // monkey
|
||||
@@ -216,7 +242,12 @@ describe('ReactDOMSelect', function() {
|
||||
expect(node.options[2].selected).toBe(false); // gorilla
|
||||
|
||||
// When making it multiple, giraffe and gorilla should be selected
|
||||
stub.setProps({multiple: true, defaultValue: ['giraffe', 'gorilla']});
|
||||
React.render(
|
||||
<select multiple={true} defaultValue={['giraffe', 'gorilla']}>
|
||||
{options}
|
||||
</select>,
|
||||
container
|
||||
);
|
||||
|
||||
expect(node.options[0].selected).toBe(false); // monkey
|
||||
expect(node.options[1].selected).toBe(true); // giraffe
|
||||
@@ -230,7 +261,9 @@ describe('ReactDOMSelect', function() {
|
||||
<option value="giraffe">A giraffe!</option>
|
||||
<option value="gorilla">A gorilla!</option>
|
||||
</select>;
|
||||
stub = ReactTestUtils.renderIntoDocument(stub);
|
||||
var options = stub.props.children;
|
||||
var container = document.createElement('div');
|
||||
stub = React.render(stub, container);
|
||||
var node = React.findDOMNode(stub);
|
||||
|
||||
expect(node.options[0].selected).toBe(false); // monkey
|
||||
@@ -239,7 +272,11 @@ describe('ReactDOMSelect', function() {
|
||||
|
||||
// When removing multiple, defaultValue is applied again, being omitted
|
||||
// means that "monkey" will be selected
|
||||
stub.setProps({multiple: false, defaultValue: 'gorilla'});
|
||||
React.render(
|
||||
<select defaultValue="gorilla">{options}</select>,
|
||||
container
|
||||
);
|
||||
|
||||
|
||||
expect(node.options[0].selected).toBe(false); // monkey
|
||||
expect(node.options[1].selected).toBe(false); // giraffe
|
||||
@@ -253,14 +290,16 @@ describe('ReactDOMSelect', function() {
|
||||
<option value="giraffe">A giraffe!</option>
|
||||
<option value="gorilla">A gorilla!</option>
|
||||
</select>;
|
||||
stub = ReactTestUtils.renderIntoDocument(stub);
|
||||
var options = stub.props.children;
|
||||
var container = document.createElement('div');
|
||||
stub = React.render(stub, container);
|
||||
var node = React.findDOMNode(stub);
|
||||
|
||||
expect(node.options[0].selected).toBe(false); // monkey
|
||||
expect(node.options[1].selected).toBe(true); // giraffe
|
||||
expect(node.options[2].selected).toBe(false); // gorilla
|
||||
|
||||
stub.setProps({value: null});
|
||||
React.render(<select>{options}</select>, container);
|
||||
|
||||
expect(node.options[0].selected).toBe(false); // monkey
|
||||
expect(node.options[1].selected).toBe(true); // giraffe
|
||||
@@ -274,16 +313,18 @@ describe('ReactDOMSelect', function() {
|
||||
<option value="giraffe">A giraffe!</option>
|
||||
<option value="gorilla">A gorilla!</option>
|
||||
</select>;
|
||||
stub = ReactTestUtils.renderIntoDocument(stub);
|
||||
var options = stub.props.children;
|
||||
var container = document.createElement('div');
|
||||
stub = React.render(stub, container);
|
||||
var node = React.findDOMNode(stub);
|
||||
|
||||
stub.setProps({value: 'gorilla'});
|
||||
React.render(<select value="gorilla">{options}</select>, container);
|
||||
|
||||
expect(node.options[0].selected).toBe(false); // monkey
|
||||
expect(node.options[1].selected).toBe(false); // giraffe
|
||||
expect(node.options[2].selected).toBe(true); // gorilla
|
||||
|
||||
stub.setProps({value: null});
|
||||
React.render(<select>{options}</select>, container);
|
||||
|
||||
expect(node.options[0].selected).toBe(false); // monkey
|
||||
expect(node.options[1].selected).toBe(false); // giraffe
|
||||
|
||||
@@ -26,8 +26,11 @@ describe('ReactDOMTextarea', function() {
|
||||
ReactLink = require('ReactLink');
|
||||
ReactTestUtils = require('ReactTestUtils');
|
||||
|
||||
renderTextarea = function(component) {
|
||||
var stub = ReactTestUtils.renderIntoDocument(component);
|
||||
renderTextarea = function(component, container) {
|
||||
if (!container) {
|
||||
container = document.createElement('div');
|
||||
}
|
||||
var stub = React.render(component, container);
|
||||
var node = React.findDOMNode(stub);
|
||||
// Fixing jsdom's quirky behavior -- in reality, the parser should strip
|
||||
// off the leading newline but we need to do it by hand here.
|
||||
@@ -37,14 +40,14 @@ describe('ReactDOMTextarea', function() {
|
||||
});
|
||||
|
||||
it('should allow setting `defaultValue`', function() {
|
||||
var stub = <textarea defaultValue="giraffe" />;
|
||||
stub = renderTextarea(stub);
|
||||
var container = document.createElement('div');
|
||||
var stub = renderTextarea(<textarea defaultValue="giraffe" />, container);
|
||||
var node = React.findDOMNode(stub);
|
||||
|
||||
expect(node.value).toBe('giraffe');
|
||||
|
||||
// Changing `defaultValue` should do nothing.
|
||||
stub.replaceProps({defaultValue: 'gorilla'});
|
||||
stub = renderTextarea(<textarea defaultValue="gorilla" />, container);
|
||||
expect(node.value).toEqual('giraffe');
|
||||
});
|
||||
|
||||
@@ -95,41 +98,54 @@ describe('ReactDOMTextarea', function() {
|
||||
});
|
||||
|
||||
it('should allow setting `value` to `giraffe`', function() {
|
||||
var container = document.createElement('div');
|
||||
var stub = <textarea value="giraffe" onChange={emptyFunction} />;
|
||||
stub = renderTextarea(stub);
|
||||
stub = renderTextarea(stub, container);
|
||||
var node = React.findDOMNode(stub);
|
||||
|
||||
expect(node.value).toBe('giraffe');
|
||||
|
||||
stub.replaceProps({value: 'gorilla', onChange: emptyFunction});
|
||||
stub = React.render(
|
||||
<textarea value="gorilla" onChange={emptyFunction} />,
|
||||
container
|
||||
);
|
||||
expect(node.value).toEqual('gorilla');
|
||||
});
|
||||
|
||||
it('should allow setting `value` to `true`', function() {
|
||||
var container = document.createElement('div');
|
||||
var stub = <textarea value="giraffe" onChange={emptyFunction} />;
|
||||
stub = renderTextarea(stub);
|
||||
stub = renderTextarea(stub, container);
|
||||
var node = React.findDOMNode(stub);
|
||||
|
||||
expect(node.value).toBe('giraffe');
|
||||
|
||||
stub.replaceProps({value: true, onChange: emptyFunction});
|
||||
stub = React.render(
|
||||
<textarea value={true} onChange={emptyFunction} />,
|
||||
container
|
||||
);
|
||||
expect(node.value).toEqual('true');
|
||||
});
|
||||
|
||||
it('should allow setting `value` to `false`', function() {
|
||||
var container = document.createElement('div');
|
||||
var stub = <textarea value="giraffe" onChange={emptyFunction} />;
|
||||
stub = renderTextarea(stub);
|
||||
stub = renderTextarea(stub, container);
|
||||
var node = React.findDOMNode(stub);
|
||||
|
||||
expect(node.value).toBe('giraffe');
|
||||
|
||||
stub.replaceProps({value: false});
|
||||
stub = React.render(
|
||||
<textarea value={false} onChange={emptyFunction} />,
|
||||
container
|
||||
);
|
||||
expect(node.value).toEqual('false');
|
||||
});
|
||||
|
||||
it('should allow setting `value` to `objToString`', function() {
|
||||
var container = document.createElement('div');
|
||||
var stub = <textarea value="giraffe" onChange={emptyFunction} />;
|
||||
stub = renderTextarea(stub);
|
||||
stub = renderTextarea(stub, container);
|
||||
var node = React.findDOMNode(stub);
|
||||
|
||||
expect(node.value).toBe('giraffe');
|
||||
@@ -139,7 +155,10 @@ describe('ReactDOMTextarea', function() {
|
||||
return 'foo';
|
||||
},
|
||||
};
|
||||
stub.replaceProps({value: objToString, onChange: emptyFunction});
|
||||
stub = React.render(
|
||||
<textarea value={objToString} onChange={emptyFunction} />,
|
||||
container
|
||||
);
|
||||
expect(node.value).toEqual('foo');
|
||||
});
|
||||
|
||||
@@ -156,15 +175,16 @@ describe('ReactDOMTextarea', function() {
|
||||
it('should treat children like `defaultValue`', function() {
|
||||
spyOn(console, 'error');
|
||||
|
||||
var container = document.createElement('div');
|
||||
var stub = <textarea>giraffe</textarea>;
|
||||
stub = renderTextarea(stub);
|
||||
stub = renderTextarea(stub, container);
|
||||
var node = React.findDOMNode(stub);
|
||||
|
||||
expect(console.error.argsForCall.length).toBe(1);
|
||||
expect(node.value).toBe('giraffe');
|
||||
|
||||
// Changing children should do nothing, it functions like `defaultValue`.
|
||||
stub.replaceProps({children: 'gorilla'});
|
||||
stub = React.render(<textarea>gorilla</textarea>, container);
|
||||
expect(node.value).toEqual('giraffe');
|
||||
});
|
||||
|
||||
|
||||
@@ -38,8 +38,27 @@ var ServerReactRootIndex = require('ServerReactRootIndex');
|
||||
var SimpleEventPlugin = require('SimpleEventPlugin');
|
||||
var SVGDOMPropertyConfig = require('SVGDOMPropertyConfig');
|
||||
|
||||
var warning = require('warning');
|
||||
|
||||
var deprecatedDOMMethods = [
|
||||
'isMounted', 'replaceProps', 'replaceState', 'setProps', 'setState',
|
||||
'forceUpdate',
|
||||
];
|
||||
|
||||
function getDeclarationErrorAddendum(domWrapperClass) {
|
||||
var internalInstance = ReactInstanceMap.get(domWrapperClass);
|
||||
var owner = internalInstance._currentElement._owner || null;
|
||||
if (owner) {
|
||||
var name = owner.getName();
|
||||
if (name) {
|
||||
return ' This DOM component was rendered by `' + name + '`.';
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
function autoGenerateWrapperClass(type) {
|
||||
return ReactClass.createClass({
|
||||
var wrapperClass = ReactClass.createClass({
|
||||
tagName: type.toUpperCase(),
|
||||
render: function() {
|
||||
// Copy owner down for debugging info
|
||||
@@ -49,10 +68,51 @@ function autoGenerateWrapperClass(type) {
|
||||
null, // key
|
||||
null, // ref
|
||||
internalInstance._currentElement._owner, // owner
|
||||
this.props
|
||||
this._internalProps
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
Object.defineProperty(wrapperClass.prototype, 'props', {
|
||||
enumerable: true,
|
||||
set: function(props) {
|
||||
this._internalProps = props;
|
||||
},
|
||||
get: function() {
|
||||
if (__DEV__) {
|
||||
warning(
|
||||
false,
|
||||
'ReactDOMComponent.props: Do not access .props of a DOM component ' +
|
||||
'directly; instead, recreate the props as `render` did originally ' +
|
||||
'or use React.findDOMNode and read the DOM properties/attributes ' +
|
||||
'directly.%s',
|
||||
getDeclarationErrorAddendum(this)
|
||||
);
|
||||
}
|
||||
return this._internalProps;
|
||||
},
|
||||
});
|
||||
|
||||
deprecatedDOMMethods.forEach(function(method) {
|
||||
var old = wrapperClass.prototype[method];
|
||||
Object.defineProperty(wrapperClass.prototype, method, {
|
||||
enumerable: true,
|
||||
get: function() {
|
||||
if (__DEV__) {
|
||||
warning(
|
||||
false,
|
||||
'ReactDOMComponent.%s(): Do not access .%s() of a DOM component.%s',
|
||||
method,
|
||||
method,
|
||||
getDeclarationErrorAddendum(this)
|
||||
);
|
||||
}
|
||||
return old;
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
return wrapperClass;
|
||||
}
|
||||
|
||||
var alreadyInjected = false;
|
||||
|
||||
@@ -902,4 +902,41 @@ describe('ReactDOMComponent', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('DOM nodes as refs', function() {
|
||||
var React;
|
||||
var ReactTestUtils;
|
||||
|
||||
beforeEach(function() {
|
||||
React = require('React');
|
||||
ReactTestUtils = require('ReactTestUtils');
|
||||
});
|
||||
|
||||
it('warns when accessing properties on DOM components', function() {
|
||||
spyOn(console, 'error');
|
||||
var Animal = React.createClass({
|
||||
render: function() {
|
||||
return <div ref="div">iguana</div>;
|
||||
},
|
||||
componentDidMount: function() {
|
||||
void this.refs.div.props;
|
||||
void this.refs.div.setProps;
|
||||
},
|
||||
});
|
||||
ReactTestUtils.renderIntoDocument(<Animal />);
|
||||
|
||||
expect(console.error.calls.length).toBe(2);
|
||||
expect(console.error.calls[0].args[0]).toBe(
|
||||
'Warning: ReactDOMComponent.props: Do not access .props of a DOM ' +
|
||||
'component directly; instead, recreate the props as `render` did ' +
|
||||
'originally or use React.findDOMNode and read the DOM ' +
|
||||
'properties/attributes directly. This DOM component was rendered ' +
|
||||
'by `Animal`.'
|
||||
);
|
||||
expect(console.error.calls[1].args[0]).toBe(
|
||||
'Warning: ReactDOMComponent.setProps(): Do not access .setProps() of ' +
|
||||
'a DOM component. This DOM component was rendered by `Animal`.'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
@@ -557,11 +557,16 @@ var ReactCompositeComponentMixin = {
|
||||
) {
|
||||
var inst = this._instance;
|
||||
|
||||
var nextContext = inst.context;
|
||||
var nextProps = inst.props;
|
||||
var nextContext;
|
||||
var nextProps;
|
||||
|
||||
// Distinguish between a props update versus a simple state update
|
||||
if (prevParentElement !== nextParentElement) {
|
||||
if (prevParentElement === nextParentElement) {
|
||||
nextContext = inst.context;
|
||||
// Skip checking prop types again -- we don't read inst.props to avoid
|
||||
// warning for DOM component props in this upgrade
|
||||
nextProps = nextParentElement.props;
|
||||
} else {
|
||||
nextContext = this._processContext(nextUnmaskedContext);
|
||||
nextProps = this._processProps(nextParentElement.props);
|
||||
|
||||
@@ -663,9 +668,15 @@ var ReactCompositeComponentMixin = {
|
||||
) {
|
||||
var inst = this._instance;
|
||||
|
||||
var prevProps = inst.props;
|
||||
var prevState = inst.state;
|
||||
var prevContext = inst.context;
|
||||
var hasComponentDidUpdate = Boolean(inst.componentDidUpdate);
|
||||
var prevProps;
|
||||
var prevState;
|
||||
var prevContext;
|
||||
if (hasComponentDidUpdate) {
|
||||
prevProps = inst.props;
|
||||
prevState = inst.state;
|
||||
prevContext = inst.context;
|
||||
}
|
||||
|
||||
if (inst.componentWillUpdate) {
|
||||
inst.componentWillUpdate(nextProps, nextState, nextContext);
|
||||
@@ -679,7 +690,7 @@ var ReactCompositeComponentMixin = {
|
||||
|
||||
this._updateRenderedComponent(transaction, unmaskedContext);
|
||||
|
||||
if (inst.componentDidUpdate) {
|
||||
if (hasComponentDidUpdate) {
|
||||
transaction.getReactMountReady().enqueue(
|
||||
inst.componentDidUpdate.bind(inst, prevProps, prevState, prevContext),
|
||||
inst
|
||||
|
||||
@@ -135,6 +135,9 @@ describe('ReactComponent', function() {
|
||||
|
||||
it('should support new-style refs with mixed-up owners', function() {
|
||||
var Wrapper = React.createClass({
|
||||
getTitle: function() {
|
||||
return this.props.title;
|
||||
},
|
||||
render: function() {
|
||||
return this.props.getContent();
|
||||
},
|
||||
@@ -158,8 +161,8 @@ describe('ReactComponent', function() {
|
||||
},
|
||||
componentDidMount: function() {
|
||||
// Check .props.title to make sure we got the right elements back
|
||||
expect(this.wrapperRef.props.title).toBe('wrapper');
|
||||
expect(this.innerRef.props.title).toBe('inner');
|
||||
expect(this.wrapperRef.getTitle()).toBe('wrapper');
|
||||
expect(React.findDOMNode(this.innerRef).title).toBe('inner');
|
||||
mounted = true;
|
||||
},
|
||||
});
|
||||
|
||||
@@ -464,15 +464,20 @@ describe('ReactComponentLifeCycle', function() {
|
||||
/**
|
||||
* calls setProps in an componentDidMount.
|
||||
*/
|
||||
var Inner = React.createClass({
|
||||
render: function() {
|
||||
return <div />;
|
||||
},
|
||||
});
|
||||
var PropsUpdaterInOnDOMReady = React.createClass({
|
||||
componentDidMount: function() {
|
||||
this.refs.theSimpleComponent.setProps({
|
||||
valueToUseInitially: this.props.valueToUseInOnDOMReady,
|
||||
className: this.props.valueToUseInOnDOMReady,
|
||||
});
|
||||
},
|
||||
render: function() {
|
||||
return (
|
||||
<div
|
||||
<Inner
|
||||
className={this.props.valueToUseInitially}
|
||||
ref="theSimpleComponent"
|
||||
/>
|
||||
|
||||
@@ -385,9 +385,14 @@ describe('ReactCompositeComponent', function() {
|
||||
|
||||
var innerInstance;
|
||||
|
||||
var Inner = React.createClass({
|
||||
render: function() {
|
||||
return <div />;
|
||||
},
|
||||
});
|
||||
var Component = React.createClass({
|
||||
render: function() {
|
||||
return <div><div ref="inner" /></div>;
|
||||
return <div><Inner ref="inner" /></div>;
|
||||
},
|
||||
componentDidMount: function() {
|
||||
innerInstance = this.refs.inner;
|
||||
|
||||
@@ -31,25 +31,16 @@ var testAllPermutations = function(testCases) {
|
||||
var updateWithChildren = testCases[j];
|
||||
var expectedResultAfterUpdate = testCases[j + 1];
|
||||
|
||||
var d = renderChildren(renderWithChildren);
|
||||
var container = document.createElement('div');
|
||||
var d = React.render(<div>{renderWithChildren}</div>, container);
|
||||
expectChildren(d, expectedResultAfterRender);
|
||||
|
||||
updateChildren(d, updateWithChildren);
|
||||
d = React.render(<div>{updateWithChildren}</div>, container);
|
||||
expectChildren(d, expectedResultAfterUpdate);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var renderChildren = function(children) {
|
||||
return ReactTestUtils.renderIntoDocument(
|
||||
<div>{children}</div>
|
||||
);
|
||||
};
|
||||
|
||||
var updateChildren = function(d, children) {
|
||||
d.replaceProps({children: children});
|
||||
};
|
||||
|
||||
var expectChildren = function(d, children) {
|
||||
var textNode;
|
||||
if (typeof children === 'string') {
|
||||
|
||||
@@ -77,6 +77,11 @@ var ReactTestUtils = {
|
||||
},
|
||||
|
||||
isCompositeComponent: function(inst) {
|
||||
if (ReactTestUtils.isDOMComponent(inst)) {
|
||||
// Accessing inst.setState warns; just return false as that'll be what
|
||||
// this returns when we have DOM nodes as refs directly
|
||||
return false;
|
||||
}
|
||||
return typeof inst.render === 'function' &&
|
||||
typeof inst.setState === 'function';
|
||||
},
|
||||
@@ -165,11 +170,14 @@ var ReactTestUtils = {
|
||||
*/
|
||||
scryRenderedDOMComponentsWithClass: function(root, className) {
|
||||
return ReactTestUtils.findAllInRenderedTree(root, function(inst) {
|
||||
var instClassName = inst.props.className;
|
||||
return ReactTestUtils.isDOMComponent(inst) && (
|
||||
instClassName &&
|
||||
(' ' + instClassName + ' ').indexOf(' ' + className + ' ') !== -1
|
||||
);
|
||||
if (ReactTestUtils.isDOMComponent(inst)) {
|
||||
var instClassName = React.findDOMNode(inst).className;
|
||||
return (
|
||||
instClassName &&
|
||||
(' ' + instClassName + ' ').indexOf(' ' + className + ' ') !== -1
|
||||
);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
Reference in new issue
Block a user