diff --git a/scripts/fiber/tests-passing.txt b/scripts/fiber/tests-passing.txt index ed67b3389a905..387a1fa69c7ea 100644 --- a/scripts/fiber/tests-passing.txt +++ b/scripts/fiber/tests-passing.txt @@ -1153,6 +1153,7 @@ src/renderers/shared/fiber/__tests__/ReactIncremental-test.js * provides context when reusing work * reads context when setState is below the provider * reads context when setState is above the provider +* maintains the correct context index when context proviers are bailed out due to low priority src/renderers/shared/fiber/__tests__/ReactIncrementalErrorHandling-test.js * catches render error in a boundary during full deferred mounting diff --git a/src/renderers/shared/fiber/ReactFiberBeginWork.js b/src/renderers/shared/fiber/ReactFiberBeginWork.js index 94799919b9179..35b3570db0581 100644 --- a/src/renderers/shared/fiber/ReactFiberBeginWork.js +++ b/src/renderers/shared/fiber/ReactFiberBeginWork.js @@ -462,8 +462,17 @@ module.exports = function( } function bailoutOnLowPriority(current, workInProgress) { - if (workInProgress.tag === HostPortal) { - pushHostContainer(workInProgress.stateNode.containerInfo); + // TODO: Handle HostComponent tags here as well and call pushHostContext()? + // See PR 8590 discussion for context + switch (workInProgress.tag) { + case ClassComponent: + if (isContextProvider(workInProgress)) { + pushContextProvider(workInProgress, false); + } + break; + case HostPortal: + pushHostContainer(workInProgress.stateNode.containerInfo); + break; } // TODO: What if this is currently in progress? // How can that happen? How is this not being cloned? diff --git a/src/renderers/shared/fiber/__tests__/ReactIncremental-test.js b/src/renderers/shared/fiber/__tests__/ReactIncremental-test.js index 9bf334b2080a1..3a91f6c3cc4a6 100644 --- a/src/renderers/shared/fiber/__tests__/ReactIncremental-test.js +++ b/src/renderers/shared/fiber/__tests__/ReactIncremental-test.js @@ -1932,4 +1932,47 @@ describe('ReactIncremental', () => { 'ShowLocaleFn:read {"locale":"gr"}', ]); }); + + it('maintains the correct context index when context proviers are bailed out due to low priority', () => { + class Root extends React.Component { + render() { + return ; + } + } + + let instance; + + class Middle extends React.Component { + constructor(props, context) { + super(props, context); + instance = this; + } + shouldComponentUpdate() { + // Return false so that our child will get a NoWork priority (and get bailed out) + return false; + } + render() { + return ; + } + } + + // Child must be a context provider to trigger the bug + class Child extends React.Component { + static childContextTypes = {}; + getChildContext() { + return {}; + } + render() { + return
; + } + } + + // Init + ReactNoop.render(); + ReactNoop.flush(); + + // Trigger an update in the middle of the tree + instance.setState({}); + ReactNoop.flush(); + }); });