@samitouri / QOS-React / commits / f829e2f1f1

Meant to commit these changes with #8206... oops.

Andrew Clark committed Nov 8, 2016 at 13:47 UTC f829e2f1f1d950db7d588a5dd288d3e39e074d4d
5 files changed +146 -66
scripts/fiber/tests-failing.txt
-3
@@ -72,9 +72,6 @@ src/renderers/art/__tests__/ReactART-test.js
72 * resolves refs before componentDidMount
73 * resolves refs before componentDidUpdate
74
75 -src/renderers/dom/__tests__/ReactDOMProduction-test.js
76 -* should throw with an error code in production
77 -
75 src/renderers/dom/shared/__tests__/CSSPropertyOperations-test.js
76 * should set style attribute when styles exist
77 * should warn when using hyphenated style names
scripts/fiber/tests-passing.txt
+3 -1
@@ -453,6 +453,7 @@ src/renderers/dom/__tests__/ReactDOMProduction-test.js
453 * should use prod React
454 * should handle a simple flow
455 * should call lifecycle methods
456 +* should throw with an error code in production
457
458 src/renderers/dom/fiber/__tests__/ReactDOMFiber-test.js
459 * should render strings as children
@@ -842,6 +843,8 @@ src/renderers/shared/fiber/__tests__/ReactIncrementalScheduling-test.js
843 * splits deferred work on multiple roots
844 * works on deferred roots in the order they were scheduled
845 * handles interleaved deferred and animation work
846 +* schedules sync updates when inside componentDidMount/Update
847 +* can opt-in to deferred/animation scheduling inside componentDidMount/Update
848
849 src/renderers/shared/fiber/__tests__/ReactIncrementalSideEffects-test.js
850 * can update child nodes of a host instance
@@ -862,7 +865,6 @@ src/renderers/shared/fiber/__tests__/ReactIncrementalSideEffects-test.js
865 * calls setState callback even if component bails out
866 * calls componentWillUnmount after a deletion, even if nested
867 * calls componentDidMount/Update after insertion/update
865 -* schedules sync updates when inside componentDidMount/Update
868 * invokes ref callbacks after insertion/update/unmount
869 * supports string refs
870
src/renderers/shared/fiber/ReactFiberScheduler.js
+5 -2
@@ -211,8 +211,11 @@ module.exports = function<T, P, I, TI, C>(config : HostConfig<T, P, I, TI, C>) {
211 const current = effectfulFiber.alternate;
212 const previousPriorityContext = priorityContext;
213 priorityContext = TaskPriority;
214 - commitLifeCycles(current, effectfulFiber);
215 - priorityContext = previousPriorityContext;
214 + try {
215 + commitLifeCycles(current, effectfulFiber);
216 + } finally {
217 + priorityContext = previousPriorityContext;
218 + }
219 }
220 const next = effectfulFiber.nextEffect;
221 // Ensure that we clean these up so that we don't accidentally keep them.
src/renderers/shared/fiber/__tests__/ReactIncrementalScheduling-test.js
+138
@@ -449,4 +449,142 @@ describe('ReactIncrementalScheduling', () => {
449 expect(ReactNoop.getChildren('b')).toEqual([span('b:3')]);
450 expect(ReactNoop.getChildren('c')).toEqual([span('c:3')]);
451 });
452 +
453 + it('schedules sync updates when inside componentDidMount/Update', () => {
454 + var instance;
455 + var ops = [];
456 +
457 + class Foo extends React.Component {
458 + state = { tick: 0 };
459 +
460 + componentDidMount() {
461 + ops.push('componentDidMount (before setState): ' + this.state.tick);
462 + this.setState({ tick: 1 });
463 + // We're in a batch. Update hasn't flushed yet.
464 + ops.push('componentDidMount (after setState): ' + this.state.tick);
465 + }
466 +
467 + componentDidUpdate() {
468 + ops.push('componentDidUpdate: ' + this.state.tick);
469 + if (this.state.tick === 2) {
470 + ops.push('componentDidUpdate (before setState): ' + this.state.tick);
471 + this.setState({ tick: 3 });
472 + ops.push('componentDidUpdate (after setState): ' + this.state.tick);
473 + // We're in a batch. Update hasn't flushed yet.
474 + }
475 + }
476 +
477 + render() {
478 + ops.push('render: ' + this.state.tick);
479 + instance = this;
480 + return <span prop={this.state.tick} />;
481 + }
482 + }
483 +
484 + ReactNoop.render(<Foo />);
485 +
486 + ReactNoop.flushDeferredPri(20);
487 + expect(ops).toEqual([
488 + 'render: 0',
489 + 'componentDidMount (before setState): 0',
490 + 'componentDidMount (after setState): 0',
491 + // If the setState inside componentDidMount were deferred, there would be
492 + // no more ops. Because it has Task priority, we get these ops, too:
493 + 'render: 1',
494 + 'componentDidUpdate: 1',
495 + ]);
496 +
497 + ops = [];
498 + instance.setState({ tick: 2 });
499 + ReactNoop.flushDeferredPri(20);
500 +
501 + expect(ops).toEqual([
502 + 'render: 2',
503 + 'componentDidUpdate: 2',
504 + 'componentDidUpdate (before setState): 2',
505 + 'componentDidUpdate (after setState): 2',
506 + // If the setState inside componentDidUpdate were deferred, there would be
507 + // no more ops. Because it has Task priority, we get these ops, too:
508 + 'render: 3',
509 + 'componentDidUpdate: 3',
510 + ]);
511 + });
512 +
513 + it('can opt-in to deferred/animation scheduling inside componentDidMount/Update', () => {
514 + var instance;
515 + var ops = [];
516 +
517 + class Foo extends React.Component {
518 + state = { tick: 0 };
519 +
520 + componentDidMount() {
521 + ReactNoop.performAnimationWork(() => {
522 + ops.push('componentDidMount (before setState): ' + this.state.tick);
523 + this.setState({ tick: 1 });
524 + ops.push('componentDidMount (after setState): ' + this.state.tick);
525 + });
526 + }
527 +
528 + componentDidUpdate() {
529 + ReactNoop.performAnimationWork(() => {
530 + ops.push('componentDidUpdate: ' + this.state.tick);
531 + if (this.state.tick === 2) {
532 + ops.push('componentDidUpdate (before setState): ' + this.state.tick);
533 + this.setState({ tick: 3 });
534 + ops.push('componentDidUpdate (after setState): ' + this.state.tick);
535 + }
536 + });
537 + }
538 +
539 + render() {
540 + ops.push('render: ' + this.state.tick);
541 + instance = this;
542 + return <span prop={this.state.tick} />;
543 + }
544 + }
545 +
546 + ReactNoop.render(<Foo />);
547 +
548 + ReactNoop.flushDeferredPri(20);
549 + expect(ops).toEqual([
550 + 'render: 0',
551 + 'componentDidMount (before setState): 0',
552 + 'componentDidMount (after setState): 0',
553 + // Following items shouldn't appear because they are the result of an
554 + // update scheduled with animation priority
555 + // 'render: 1',
556 + // 'componentDidUpdate: 1',
557 + ]);
558 +
559 + ops = [];
560 +
561 + ReactNoop.flushAnimationPri();
562 + expect(ops).toEqual([
563 + 'render: 1',
564 + 'componentDidUpdate: 1',
565 + ]);
566 +
567 + ops = [];
568 + instance.setState({ tick: 2 });
569 + ReactNoop.flushDeferredPri(20);
570 +
571 + expect(ops).toEqual([
572 + 'render: 2',
573 + 'componentDidUpdate: 2',
574 + 'componentDidUpdate (before setState): 2',
575 + 'componentDidUpdate (after setState): 2',
576 + // Following items shouldn't appear because they are the result of an
577 + // update scheduled with animation priority
578 + // 'render: 3',
579 + // 'componentDidUpdate: 3',
580 + ]);
581 +
582 + ops = [];
583 +
584 + ReactNoop.flushAnimationPri();
585 + expect(ops).toEqual([
586 + 'render: 3',
587 + 'componentDidUpdate: 3',
588 + ]);
589 + });
590 });
src/renderers/shared/fiber/__tests__/ReactIncrementalSideEffects-test.js
-60
@@ -1036,66 +1036,6 @@ describe('ReactIncrementalSideEffects', () => {
1036
1037 });
1038
1039 - it('schedules sync updates when inside componentDidMount/Update', () => {
1040 - var instance;
1041 - var ops = [];
1042 -
1043 - class Foo extends React.Component {
1044 - state = { tick: 0 };
1045 -
1046 - componentDidMount() {
1047 - ops.push('componentDidMount (before setState): ' + this.state.tick);
1048 - this.setState({ tick: 1 });
1049 - // We're in a batch. Update hasn't flushed yet.
1050 - ops.push('componentDidMount (after setState): ' + this.state.tick);
1051 - }
1052 -
1053 - componentDidUpdate() {
1054 - ops.push('componentDidUpdate: ' + this.state.tick);
1055 - if (this.state.tick === 2) {
1056 - ops.push('componentDidUpdate (before setState): ' + this.state.tick);
1057 - this.setState({ tick: 3 });
1058 - ops.push('componentDidUpdate (after setState): ' + this.state.tick);
1059 - // We're in a batch. Update hasn't flushed yet.
1060 - }
1061 - }
1062 -
1063 - render() {
1064 - ops.push('render: ' + this.state.tick);
1065 - instance = this;
1066 - return <span prop={this.state.tick} />;
1067 - }
1068 - }
1069 -
1070 - ReactNoop.render(<Foo />);
1071 -
1072 - ReactNoop.flushDeferredPri(20);
1073 - expect(ops).toEqual([
1074 - 'render: 0',
1075 - 'componentDidMount (before setState): 0',
1076 - 'componentDidMount (after setState): 0',
1077 - // If the setState inside componentDidMount were deferred, there would be
1078 - // no more ops. Because it has Task priority, we get these ops, too:
1079 - 'render: 1',
1080 - 'componentDidUpdate: 1',
1081 - ]);
1082 -
1083 - ops = [];
1084 - instance.setState({ tick: 2 });
1085 - ReactNoop.flushDeferredPri(20);
1086 -
1087 - expect(ops).toEqual([
1088 - 'render: 2',
1089 - 'componentDidUpdate: 2',
1090 - 'componentDidUpdate (before setState): 2',
1091 - 'componentDidUpdate (after setState): 2',
1092 - // If the setState inside componentDidUpdate were deferred, there would be
1093 - // no more ops. Because it has Task priority, we get these ops, too:
1094 - 'render: 3',
1095 - 'componentDidUpdate: 3',
1096 - ]);
1097 - });
1098 -
1039 it('invokes ref callbacks after insertion/update/unmount', () => {
1040
1041 var classInstance = null;