@samitouri / QOS-React-2 / commits / 441cc5c82b

bailoutOnLowPriority correct pushes context for ClassComponents to mirror complete phase context pop

Brian Vaughn committed Dec 16, 2016 at 15:04 UTC 441cc5c82b93dd2a7b75292cea5fdd745cc00999
3 files changed +55 -2
scripts/fiber/tests-passing.txt
+1
@@ -1148,6 +1148,7 @@ src/renderers/shared/fiber/__tests__/ReactIncremental-test.js
1148 * provides context when reusing work
1149 * reads context when setState is below the provider
1150 * reads context when setState is above the provider
1151 +* maintains the correct context index when context proviers are bailed out due to low priority
1152
1153 src/renderers/shared/fiber/__tests__/ReactIncrementalErrorHandling-test.js
1154 * catches render error in a boundary during full deferred mounting
src/renderers/shared/fiber/ReactFiberBeginWork.js
+11 -2
@@ -462,8 +462,17 @@ module.exports = function<T, P, I, TI, C, CX>(
462 }
463
464 function bailoutOnLowPriority(current, workInProgress) {
465 - if (workInProgress.tag === HostPortal) {
466 - pushHostContainer(workInProgress.stateNode.containerInfo);
465 + // TODO: Handle HostComponent tags here as well and call pushHostContext()?
466 + // See PR 8590 discussion for context
467 + switch (workInProgress.tag) {
468 + case ClassComponent:
469 + if (isContextProvider(workInProgress)) {
470 + pushContextProvider(workInProgress, false);
471 + }
472 + break;
473 + case HostPortal:
474 + pushHostContainer(workInProgress.stateNode.containerInfo);
475 + break;
476 }
477 // TODO: What if this is currently in progress?
478 // How can that happen? How is this not being cloned?
src/renderers/shared/fiber/__tests__/ReactIncremental-test.js
+43
@@ -1932,4 +1932,47 @@ describe('ReactIncremental', () => {
1932 'ShowLocaleFn:read {"locale":"gr"}',
1933 ]);
1934 });
1935 +
1936 + it('maintains the correct context index when context proviers are bailed out due to low priority', () => {
1937 + class Root extends React.Component {
1938 + render() {
1939 + return <Middle {...this.props} />;
1940 + }
1941 + }
1942 +
1943 + let instance;
1944 +
1945 + class Middle extends React.Component {
1946 + constructor(props, context) {
1947 + super(props, context);
1948 + instance = this;
1949 + }
1950 + shouldComponentUpdate() {
1951 + // Return false so that our child will get a NoWork priority (and get bailed out)
1952 + return false;
1953 + }
1954 + render() {
1955 + return <Child />;
1956 + }
1957 + }
1958 +
1959 + // Child must be a context provider to trigger the bug
1960 + class Child extends React.Component {
1961 + static childContextTypes = {};
1962 + getChildContext() {
1963 + return {};
1964 + }
1965 + render() {
1966 + return <div />;
1967 + }
1968 + }
1969 +
1970 + // Init
1971 + ReactNoop.render(<Root />);
1972 + ReactNoop.flush();
1973 +
1974 + // Trigger an update in the middle of the tree
1975 + instance.setState({});
1976 + ReactNoop.flush();
1977 + });
1978 });