@samitouri / QOS-React-2 / commits / 4eb889b72e

Revert "Removed setProps and replaceProps (both previously deprecated)"

This reverts commit 721fe7354142c866db2ebcc727a2472a3f3e0cc6. We'll keep these with a warning for one more release.

Ben Alpert committed Jul 3, 2015 at 10:09 UTC 4eb889b72ee13402d1a0b10e9458c95d7445f7e1
16 files changed +386 -45
src/isomorphic/classic/__tests__/ReactContextValidator-test.js
+3 -3
@@ -121,9 +121,9 @@ describe('ReactContextValidator', function() {
121 },
122 });
123
124 - var container = document.createElement('div');
125 - React.render(<Parent foo="abc" />, container);
126 - React.render(<Parent foo="def" />, container);
124 + var instance = <Parent foo="abc" />;
125 + instance = ReactTestUtils.renderIntoDocument(instance);
126 + instance.replaceProps({foo: 'def'});
127 expect(actualComponentWillReceiveProps).toEqual({foo: 'def'});
128 expect(actualShouldComponentUpdate).toEqual({foo: 'def'});
129 expect(actualComponentWillUpdate).toEqual({foo: 'def'});
src/isomorphic/classic/class/ReactClass.js
+32
@@ -728,6 +728,38 @@ var ReactClassMixin = {
728 isMounted: function() {
729 return this.updater.isMounted(this);
730 },
731 +
732 + /**
733 + * Sets a subset of the props.
734 + *
735 + * @param {object} partialProps Subset of the next props.
736 + * @param {?function} callback Called after props are updated.
737 + * @final
738 + * @public
739 + * @deprecated
740 + */
741 + setProps: function(partialProps, callback) {
742 + this.updater.enqueueSetProps(this, partialProps);
743 + if (callback) {
744 + this.updater.enqueueCallback(this, callback);
745 + }
746 + },
747 +
748 + /**
749 + * Replace all the props.
750 + *
751 + * @param {object} newProps Subset of the next props.
752 + * @param {?function} callback Called after props are updated.
753 + * @final
754 + * @public
755 + * @deprecated
756 + */
757 + replaceProps: function(newProps, callback) {
758 + this.updater.enqueueReplaceProps(this, newProps);
759 + if (callback) {
760 + this.updater.enqueueCallback(this, callback);
761 + }
762 + },
763 };
764
765 var ReactClassComponent = function() {};
src/isomorphic/modern/class/ReactComponent.js
+8
@@ -112,11 +112,19 @@ if (__DEV__) {
112 'Instead, make sure to clean up subscriptions and pending requests in ' +
113 'componentWillUnmount to prevent memory leaks.',
114 ],
115 + replaceProps: [
116 + 'replaceProps',
117 + 'Instead, call React.render again at the top level.',
118 + ],
119 replaceState: [
120 'replaceState',
121 'Refactor your code to use setState instead (see ' +
122 'https://github.com/facebook/react/issues/3236).',
123 ],
124 + setProps: [
125 + 'setProps',
126 + 'Instead, call React.render again at the top level.',
127 + ],
128 };
129 var defineDeprecationWarning = function(methodName, info) {
130 try {
src/isomorphic/modern/class/ReactNoopUpdateQueue.js
+23
@@ -98,6 +98,29 @@ var ReactNoopUpdateQueue = {
98 enqueueSetState: function(publicInstance, partialState) {
99 warnTDZ(publicInstance, 'setState');
100 },
101 +
102 + /**
103 + * Sets a subset of the props.
104 + *
105 + * @param {ReactClass} publicInstance The instance that should rerender.
106 + * @param {object} partialProps Subset of the next props.
107 + * @internal
108 + */
109 + enqueueSetProps: function(publicInstance, partialProps) {
110 + warnTDZ(publicInstance, 'setProps');
111 + },
112 +
113 + /**
114 + * Replaces all of the props.
115 + *
116 + * @param {ReactClass} publicInstance The instance that should rerender.
117 + * @param {object} props New props.
118 + * @internal
119 + */
120 + enqueueReplaceProps: function(publicInstance, props) {
121 + warnTDZ(publicInstance, 'replaceProps');
122 + },
123 +
124 };
125
126 module.exports = ReactNoopUpdateQueue;
src/isomorphic/modern/class/__tests__/ReactCoffeeScriptClass-test.coffee
+9 -1
@@ -346,7 +346,9 @@ describe 'ReactCoffeeScriptClass', ->
346 expect(-> instance.getDOMNode()).toThrow()
347 expect(-> instance.replaceState {}).toThrow()
348 expect(-> instance.isMounted()).toThrow()
349 - expect(console.error.calls.length).toBe 3
349 + expect(-> instance.setProps name: 'bar').toThrow()
350 + expect(-> instance.replaceProps name: 'bar').toThrow()
351 + expect(console.error.calls.length).toBe 5
352 expect(console.error.calls[0].args[0]).toContain(
353 'getDOMNode(...) is deprecated in plain JavaScript React classes'
354 )
@@ -356,6 +358,12 @@ describe 'ReactCoffeeScriptClass', ->
358 expect(console.error.calls[2].args[0]).toContain(
359 'isMounted(...) is deprecated in plain JavaScript React classes'
360 )
361 + expect(console.error.calls[3].args[0]).toContain(
362 + 'setProps(...) is deprecated in plain JavaScript React classes'
363 + )
364 + expect(console.error.calls[4].args[0]).toContain(
365 + 'replaceProps(...) is deprecated in plain JavaScript React classes'
366 + )
367
368 it 'supports this.context passed via getChildContext', ->
369 class Bar
src/isomorphic/modern/class/__tests__/ReactES6Class-test.js
+9 -1
@@ -404,7 +404,9 @@ describe('ReactES6Class', function() {
404 expect(() => instance.getDOMNode()).toThrow();
405 expect(() => instance.replaceState({})).toThrow();
406 expect(() => instance.isMounted()).toThrow();
407 - expect(console.error.calls.length).toBe(3);
407 + expect(() => instance.setProps({name: 'bar'})).toThrow();
408 + expect(() => instance.replaceProps({name: 'bar'})).toThrow();
409 + expect(console.error.calls.length).toBe(5);
410 expect(console.error.calls[0].args[0]).toContain(
411 'getDOMNode(...) is deprecated in plain JavaScript React classes. ' +
412 'Use React.findDOMNode(component) instead.'
@@ -415,6 +417,12 @@ describe('ReactES6Class', function() {
417 expect(console.error.calls[2].args[0]).toContain(
418 'isMounted(...) is deprecated in plain JavaScript React classes'
419 );
420 + expect(console.error.calls[3].args[0]).toContain(
421 + 'setProps(...) is deprecated in plain JavaScript React classes'
422 + );
423 + expect(console.error.calls[4].args[0]).toContain(
424 + 'replaceProps(...) is deprecated in plain JavaScript React classes'
425 + );
426 });
427
428 it('supports this.context passed via getChildContext', function() {
src/isomorphic/modern/class/__tests__/ReactTypeScriptClass-test.ts
+9 -1
@@ -492,7 +492,9 @@ describe('ReactTypeScriptClass', function() {
492 expect(() => instance.getDOMNode()).toThrow();
493 expect(() => instance.replaceState({})).toThrow();
494 expect(() => instance.isMounted()).toThrow();
495 - expect((<any>console.error).argsForCall.length).toBe(3);
495 + expect(() => instance.setProps({ name: 'bar' })).toThrow();
496 + expect(() => instance.replaceProps({ name: 'bar' })).toThrow();
497 + expect((<any>console.error).argsForCall.length).toBe(5);
498 expect((<any>console.error).argsForCall[0][0]).toContain(
499 'getDOMNode(...) is deprecated in plain JavaScript React classes'
500 );
@@ -502,6 +504,12 @@ describe('ReactTypeScriptClass', function() {
504 expect((<any>console.error).argsForCall[2][0]).toContain(
505 'isMounted(...) is deprecated in plain JavaScript React classes'
506 );
507 + expect((<any>console.error).argsForCall[3][0]).toContain(
508 + 'setProps(...) is deprecated in plain JavaScript React classes'
509 + );
510 + expect((<any>console.error).argsForCall[4][0]).toContain(
511 + 'replaceProps(...) is deprecated in plain JavaScript React classes'
512 + );
513 });
514
515 it('supports this.context passed via getChildContext', function() {
src/renderers/dom/shared/ReactDOMComponent.js
+41
@@ -30,6 +30,7 @@ var ReactDOMTextarea = require('ReactDOMTextarea');
30 var ReactMount = require('ReactMount');
31 var ReactMultiChild = require('ReactMultiChild');
32 var ReactPerf = require('ReactPerf');
33 +var ReactUpdateQueue = require('ReactUpdateQueue');
34
35 var assign = require('Object.assign');
36 var escapeTextContentForBrowser = require('escapeTextContentForBrowser');
@@ -129,6 +130,44 @@ function legacySetStateEtc() {
130 }
131 }
132
133 +function legacySetProps(partialProps, callback) {
134 + var component = this._reactInternalComponent;
135 + if (__DEV__) {
136 + warning(
137 + false,
138 + 'ReactDOMComponent: Do not access .setProps() of a DOM node. ' +
139 + 'Instead, call React.render again at the top level.%s',
140 + getDeclarationErrorAddendum(component)
141 + );
142 + }
143 + if (!component) {
144 + return;
145 + }
146 + ReactUpdateQueue.enqueueSetPropsInternal(component, partialProps);
147 + if (callback) {
148 + ReactUpdateQueue.enqueueCallbackInternal(component, callback);
149 + }
150 +}
151 +
152 +function legacyReplaceProps(partialProps, callback) {
153 + var component = this._reactInternalComponent;
154 + if (__DEV__) {
155 + warning(
156 + false,
157 + 'ReactDOMComponent: Do not access .replaceProps() of a DOM node. ' +
158 + 'Instead, call React.render again at the top level.%s',
159 + getDeclarationErrorAddendum(component)
160 + );
161 + }
162 + if (!component) {
163 + return;
164 + }
165 + ReactUpdateQueue.enqueueReplacePropsInternal(component, partialProps);
166 + if (callback) {
167 + ReactUpdateQueue.enqueueCallbackInternal(component, callback);
168 + }
169 +}
170 +
171 var styleMutationWarning = {};
172
173 function checkAndWarnForMutatedStyle(style1, style2, component) {
@@ -919,6 +958,8 @@ ReactDOMComponent.Mixin = {
958 node.setState = legacySetStateEtc;
959 node.replaceState = legacySetStateEtc;
960 node.forceUpdate = legacySetStateEtc;
961 + node.setProps = legacySetProps;
962 + node.replaceProps = legacyReplaceProps;
963
964 if (__DEV__) {
965 if (canDefineProperty) {
src/renderers/dom/shared/__tests__/ReactDOMComponent-test.js
+23
@@ -974,6 +974,29 @@ describe('ReactDOMComponent', function() {
974 expect(console.error.calls[4].args[0]).toContain('isMounted');
975 });
976
977 + it('handles legacy setProps and replaceProps', function() {
978 + spyOn(console, 'error');
979 + var node = ReactTestUtils.renderIntoDocument(<div>rhinoceros</div>);
980 +
981 + node.setProps({className: 'herbiverous'});
982 + expect(node.className).toBe('herbiverous');
983 + expect(node.textContent).toBe('rhinoceros');
984 +
985 + node.replaceProps({className: 'invisible rhino'});
986 + expect(node.className).toBe('invisible rhino');
987 + expect(node.textContent).toBe('');
988 +
989 + expect(console.error.calls.length).toBe(2);
990 + expect(console.error.calls[0].args[0]).toBe(
991 + 'Warning: ReactDOMComponent: Do not access .setProps() of a DOM node. ' +
992 + 'Instead, call React.render again at the top level.'
993 + );
994 + expect(console.error.calls[1].args[0]).toBe(
995 + 'Warning: ReactDOMComponent: Do not access .replaceProps() of a DOM ' +
996 + 'node. Instead, call React.render again at the top level.'
997 + );
998 + });
999 +
1000 it('does not touch ref-less nodes', function() {
1001 var node = ReactTestUtils.renderIntoDocument(<div><span /></div>);
1002 expect(typeof node.getDOMNode).toBe('function');
src/renderers/shared/reconciler/ReactUpdateQueue.js
+89 -2
@@ -12,9 +12,11 @@
12 'use strict';
13
14 var ReactCurrentOwner = require('ReactCurrentOwner');
15 +var ReactElement = require('ReactElement');
16 var ReactInstanceMap = require('ReactInstanceMap');
17 var ReactUpdates = require('ReactUpdates');
18
19 +var assign = require('Object.assign');
20 var invariant = require('invariant');
21 var warning = require('warning');
22
@@ -106,7 +108,7 @@ var ReactUpdateQueue = {
108 enqueueCallback: function(publicInstance, callback) {
109 invariant(
110 typeof callback === 'function',
109 - 'enqueueCallback(...): You called ' +
111 + 'enqueueCallback(...): You called `setProps`, `replaceProps`, ' +
112 '`setState`, `replaceState`, or `forceUpdate` with a callback that ' +
113 'isn\'t callable.'
114 );
@@ -136,7 +138,7 @@ var ReactUpdateQueue = {
138 enqueueCallbackInternal: function(internalInstance, callback) {
139 invariant(
140 typeof callback === 'function',
139 - 'enqueueCallback(...): You called ' +
141 + 'enqueueCallback(...): You called `setProps`, `replaceProps`, ' +
142 '`setState`, `replaceState`, or `forceUpdate` with a callback that ' +
143 'isn\'t callable.'
144 );
@@ -231,6 +233,91 @@ var ReactUpdateQueue = {
233 enqueueUpdate(internalInstance);
234 },
235
236 + /**
237 + * Sets a subset of the props.
238 + *
239 + * @param {ReactClass} publicInstance The instance that should rerender.
240 + * @param {object} partialProps Subset of the next props.
241 + * @internal
242 + */
243 + enqueueSetProps: function(publicInstance, partialProps) {
244 + var internalInstance = getInternalInstanceReadyForUpdate(
245 + publicInstance,
246 + 'setProps'
247 + );
248 + if (!internalInstance) {
249 + return;
250 + }
251 + ReactUpdateQueue.enqueueSetPropsInternal(internalInstance, partialProps);
252 + },
253 +
254 + enqueueSetPropsInternal: function(internalInstance, partialProps) {
255 + var topLevelWrapper = internalInstance._topLevelWrapper;
256 + invariant(
257 + topLevelWrapper,
258 + 'setProps(...): You called `setProps` on a ' +
259 + 'component with a parent. This is an anti-pattern since props will ' +
260 + 'get reactively updated when rendered. Instead, change the owner\'s ' +
261 + '`render` method to pass the correct value as props to the component ' +
262 + 'where it is created.'
263 + );
264 +
265 + // Merge with the pending element if it exists, otherwise with existing
266 + // element props.
267 + var wrapElement = topLevelWrapper._pendingElement ||
268 + topLevelWrapper._currentElement;
269 + var element = wrapElement.props;
270 + var props = assign({}, element.props, partialProps);
271 + topLevelWrapper._pendingElement = ReactElement.cloneAndReplaceProps(
272 + wrapElement,
273 + ReactElement.cloneAndReplaceProps(element, props)
274 + );
275 +
276 + enqueueUpdate(topLevelWrapper);
277 + },
278 +
279 + /**
280 + * Replaces all of the props.
281 + *
282 + * @param {ReactClass} publicInstance The instance that should rerender.
283 + * @param {object} props New props.
284 + * @internal
285 + */
286 + enqueueReplaceProps: function(publicInstance, props) {
287 + var internalInstance = getInternalInstanceReadyForUpdate(
288 + publicInstance,
289 + 'replaceProps'
290 + );
291 + if (!internalInstance) {
292 + return;
293 + }
294 + ReactUpdateQueue.enqueueReplacePropsInternal(internalInstance, props);
295 + },
296 +
297 + enqueueReplacePropsInternal: function(internalInstance, props) {
298 + var topLevelWrapper = internalInstance._topLevelWrapper;
299 + invariant(
300 + topLevelWrapper,
301 + 'replaceProps(...): You called `replaceProps` on a ' +
302 + 'component with a parent. This is an anti-pattern since props will ' +
303 + 'get reactively updated when rendered. Instead, change the owner\'s ' +
304 + '`render` method to pass the correct value as props to the component ' +
305 + 'where it is created.'
306 + );
307 +
308 + // Merge with the pending element if it exists, otherwise with existing
309 + // element props.
310 + var wrapElement = topLevelWrapper._pendingElement ||
311 + topLevelWrapper._currentElement;
312 + var element = wrapElement.props;
313 + topLevelWrapper._pendingElement = ReactElement.cloneAndReplaceProps(
314 + wrapElement,
315 + ReactElement.cloneAndReplaceProps(element, props)
316 + );
317 +
318 + enqueueUpdate(topLevelWrapper);
319 + },
320 +
321 enqueueElementInternal: function(internalInstance, newElement) {
322 internalInstance._pendingElement = newElement;
323 enqueueUpdate(internalInstance);
src/renderers/shared/reconciler/ReactUpdates.js
+1 -1
@@ -199,7 +199,7 @@ function enqueueUpdate(component) {
199 // Various parts of our code (such as ReactCompositeComponent's
200 // _renderValidatedComponent) assume that calls to render aren't nested;
201 // verify that that's the case. (This is called by each top-level update
202 - // function, like setState, forceUpdate, etc.; creation and
202 + // function, like setProps, setState, forceUpdate, etc.; creation and
203 // destruction of top-level components is guarded in ReactMount.)
204
205 if (!batchingStrategy.isBatchingUpdates) {
src/renderers/shared/reconciler/__tests__/ReactComponentLifeCycle-test.js
+56 -10
@@ -442,6 +442,46 @@ describe('ReactComponentLifeCycle', function() {
442 expect(instance.state).toEqual(POST_WILL_UNMOUNT_STATE);
443 });
444
445 + it('should throw when calling setProps() on an owned component', function() {
446 + /**
447 + * calls setProps in an componentDidMount.
448 + */
449 + var Inner = React.createClass({
450 + render: function() {
451 + return <div />;
452 + },
453 + });
454 + var PropsUpdaterInOnDOMReady = React.createClass({
455 + componentDidMount: function() {
456 + this.refs.theSimpleComponent.setProps({
457 + className: this.props.valueToUseInOnDOMReady,
458 + });
459 + },
460 + render: function() {
461 + return (
462 + <Inner
463 + className={this.props.valueToUseInitially}
464 + ref="theSimpleComponent"
465 + />
466 + );
467 + },
468 + });
469 + var instance =
470 + <PropsUpdaterInOnDOMReady
471 + valueToUseInitially="hello"
472 + valueToUseInOnDOMReady="goodbye"
473 + />;
474 + expect(function() {
475 + instance = ReactTestUtils.renderIntoDocument(instance);
476 + }).toThrow(
477 + 'Invariant Violation: setProps(...): You called `setProps` on a ' +
478 + 'component with a parent. This is an anti-pattern since props will get ' +
479 + 'reactively updated when rendered. Instead, change the owner\'s ' +
480 + '`render` method to pass the correct value as props to the component ' +
481 + 'where it is created.'
482 + );
483 + });
484 +
485 it('should not throw when updating an auxiliary component', function() {
486 var Tooltip = React.createClass({
487 render: function() {
@@ -472,18 +512,24 @@ describe('ReactComponentLifeCycle', function() {
512 },
513 });
514
475 - var container = document.createElement('div');
476 - React.render(
477 - <Component text="uno" tooltipText="one" />,
478 - container
515 + var instance = ReactTestUtils.renderIntoDocument(
516 + <Component text="uno" tooltipText="one" />
517 );
518
519 // Since `instance` is a root component, we can set its props. This also
520 // makes Tooltip rerender the tooltip component, which shouldn't throw.
483 - React.render(
484 - <Component text="dos" tooltipText="two" />,
485 - container
486 - );
521 + instance.setProps({text: 'dos', tooltipText: 'two'});
522 + });
523 +
524 + it('should not allow setProps() called on an unmounted element',
525 + function() {
526 + var PropsToUpdate = React.createClass({
527 + render: function() {
528 + return <div className={this.props.value} ref="theSimpleComponent" />;
529 + },
530 + });
531 + var instance = <PropsToUpdate value="hello" />;
532 + expect(instance.setProps).not.toBeDefined();
533 });
534
535 it('should allow state updates in componentDidMount', function() {
@@ -549,7 +595,7 @@ describe('ReactComponentLifeCycle', function() {
595
596 var container = document.createElement('div');
597 log = [];
552 - React.render(<Outer x={17} />, container);
598 + var instance = React.render(<Outer x={17} />, container);
599 expect(log).toEqual([
600 'outer componentWillMount',
601 'inner componentWillMount',
@@ -558,7 +604,7 @@ describe('ReactComponentLifeCycle', function() {
604 ]);
605
606 log = [];
561 - React.render(<Outer x={42} />, container);
607 + instance.setProps({x: 42});
608 expect(log).toEqual([
609 'outer componentWillReceiveProps',
610 'outer shouldComponentUpdate',
src/renderers/shared/reconciler/__tests__/ReactCompositeComponent-test.js
+71 -3
@@ -138,7 +138,10 @@ describe('ReactCompositeComponent', function() {
138 it('should not cache old DOM nodes when switching constructors', function() {
139 var instance = <ChildUpdates renderAnchor={true} anchorClassOn={false}/>;
140 instance = ReactTestUtils.renderIntoDocument(instance);
141 + instance.setProps({anchorClassOn: true}); // Warm any cache
142 + instance.setProps({renderAnchor: false}); // Clear out the anchor
143 // rerender
144 + instance.setProps({renderAnchor: true, anchorClassOn: false});
145 var anchor = instance.getAnchor();
146 var actualDOMAnchorNode = React.findDOMNode(anchor);
147 expect(actualDOMAnchorNode.className).toBe('');
@@ -396,6 +399,72 @@ describe('ReactCompositeComponent', function() {
399 expect(instance2.state.value).toBe(1);
400 });
401
402 + it('should not allow `setProps` on unmounted components', function() {
403 + var container = document.createElement('div');
404 + document.body.appendChild(container);
405 +
406 + var Component = React.createClass({
407 + render: function() {
408 + return <div />;
409 + },
410 + });
411 +
412 + var instance = <Component />;
413 + expect(instance.setProps).not.toBeDefined();
414 +
415 + instance = React.render(instance, container);
416 + expect(function() {
417 + instance.setProps({value: 1});
418 + }).not.toThrow();
419 + expect(console.error.calls.length).toBe(0);
420 +
421 + React.unmountComponentAtNode(container);
422 + expect(function() {
423 + instance.setProps({value: 2});
424 + }).not.toThrow();
425 +
426 + expect(console.error.calls.length).toBe(1);
427 + expect(console.error.argsForCall[0][0]).toBe(
428 + 'Warning: setProps(...): Can only update a mounted or ' +
429 + 'mounting component. This usually means you called setProps() on an ' +
430 + 'unmounted component. This is a no-op. Please check the code for the ' +
431 + 'Component component.'
432 + );
433 + });
434 +
435 + it('should only allow `setProps` on top-level components', function() {
436 + var container = document.createElement('div');
437 + document.body.appendChild(container);
438 +
439 + var innerInstance;
440 +
441 + var Inner = React.createClass({
442 + render: function() {
443 + return <div />;
444 + },
445 + });
446 + var Component = React.createClass({
447 + render: function() {
448 + return <div><Inner ref="inner" /></div>;
449 + },
450 + componentDidMount: function() {
451 + innerInstance = this.refs.inner;
452 + },
453 + });
454 + React.render(<Component />, container);
455 +
456 + expect(innerInstance).not.toBe(undefined);
457 + expect(function() {
458 + innerInstance.setProps({value: 1});
459 + }).toThrow(
460 + 'Invariant Violation: setProps(...): You called `setProps` on a ' +
461 + 'component with a parent. This is an anti-pattern since props will get ' +
462 + 'reactively updated when rendered. Instead, change the owner\'s ' +
463 + '`render` method to pass the correct value as props to the component ' +
464 + 'where it is created.'
465 + );
466 + });
467 +
468 it('should cleanup even if render() fatals', function() {
469 var BadComponent = React.createClass({
470 render: function() {
@@ -866,8 +935,7 @@ describe('ReactCompositeComponent', function() {
935 },
936 });
937
869 - var container = document.createElement('div');
870 - var comp = React.render(<Component flipped={false} />, container);
938 + var comp = ReactTestUtils.renderIntoDocument(<Component flipped={false} />);
939 expect(React.findDOMNode(comp.refs.static0).textContent).toBe('A');
940 expect(React.findDOMNode(comp.refs.static1).textContent).toBe('B');
941
@@ -878,7 +946,7 @@ describe('ReactCompositeComponent', function() {
946
947 // When flipping the order, the refs should update even though the actual
948 // contents do not
881 - React.render(<Component flipped={true} />, container);
949 + comp.setProps({flipped: true});
950 expect(React.findDOMNode(comp.refs.static0).textContent).toBe('B');
951 expect(React.findDOMNode(comp.refs.static1).textContent).toBe('A');
952
src/renderers/shared/reconciler/__tests__/ReactCompositeComponentState-test.js
+2 -3
@@ -138,9 +138,8 @@ describe('ReactCompositeComponent-state', function() {
138 this.peekAtState('initial-callback');
139 }
140 );
141 - React.render(
142 - <TestComponent stateListener={stateListener} nextColor="green" />,
143 - container,
141 + instance.setProps(
142 + {nextColor: 'green'},
143 instance.peekAtCallback('setProps')
144 );
145 instance.setFavoriteColor('blue');
src/renderers/shared/reconciler/__tests__/ReactMultiChildReconcile-test.js
+8 -20
@@ -15,6 +15,7 @@ require('mock-modules');
15
16 var React = require('React');
17 var ReactInstanceMap = require('ReactInstanceMap');
18 +var ReactTestUtils = require('ReactTestUtils');
19 var ReactMount = require('ReactMount');
20
21 var mapObject = require('mapObject');
@@ -211,20 +212,15 @@ function verifyDomOrderingAccurate(parentInstance, statusDisplays) {
212 */
213 function testPropsSequence(sequence) {
214 var i;
214 - var container = document.createElement('div');
215 - var parentInstance = React.render(
216 - <FriendsStatusDisplay {...sequence[0]} />,
217 - container
215 + var parentInstance = ReactTestUtils.renderIntoDocument(
216 + <FriendsStatusDisplay {...sequence[0]} />
217 );
218 var statusDisplays = parentInstance.getStatusDisplays();
219 var lastInternalStates = getInteralStateByUserName(statusDisplays);
220 verifyStatuses(statusDisplays, sequence[0]);
221
222 for (i = 1; i < sequence.length; i++) {
224 - React.render(
225 - <FriendsStatusDisplay {...sequence[i]} />,
226 - container
227 - );
223 + parentInstance.replaceProps(sequence[i]);
224 statusDisplays = parentInstance.getStatusDisplays();
225 verifyStatuses(statusDisplays, sequence[i]);
226 verifyStatesPreserved(lastInternalStates, statusDisplays);
@@ -247,27 +243,19 @@ describe('ReactMultiChildReconcile', function() {
243 },
244 };
245
250 - var container = document.createElement('div');
251 - var parentInstance = React.render(
252 - <FriendsStatusDisplay {...props} />,
253 - container
246 + var parentInstance = ReactTestUtils.renderIntoDocument(
247 + <FriendsStatusDisplay {...props} />
248 );
249 var statusDisplays = parentInstance.getStatusDisplays();
250 var startingInternalState = statusDisplays.jcw.getInternalState();
251
252 // Now remove the child.
259 - React.render(
260 - <FriendsStatusDisplay />,
261 - container
262 - );
253 + parentInstance.replaceProps({usernameToStatus: {} });
254 statusDisplays = parentInstance.getStatusDisplays();
255 expect(statusDisplays.jcw).toBeFalsy();
256
257 // Now reset the props that cause there to be a child
267 - React.render(
268 - <FriendsStatusDisplay {...props} />,
269 - container
270 - );
258 + parentInstance.replaceProps(props);
259 statusDisplays = parentInstance.getStatusDisplays();
260 expect(statusDisplays.jcw).toBeTruthy();
261 expect(statusDisplays.jcw.getInternalState())
src/renderers/shared/reconciler/__tests__/ReactUpdates-test.js
+2
@@ -100,12 +100,14 @@ describe('ReactUpdates', function() {
100 expect(instance.state.y).toBe(0);
101
102 ReactUpdates.batchedUpdates(function() {
103 + instance.setProps({x: 1});
104 instance.setState({y: 2});
105 expect(instance.props.x).toBe(0);
106 expect(instance.state.y).toBe(0);
107 expect(updateCount).toBe(0);
108 });
109
110 + expect(instance.props.x).toBe(1);
111 expect(instance.state.y).toBe(2);
112 expect(updateCount).toBe(1);
113 });