A <Context.Consumer> callback inside a suspended <Suspense> boundary does not receive updates when context value changes.
This issue was originally found with React Router (remix-run/react-router#7137) but can be reproduced with React alone.
React version: 16.13.1 or 17.0.0-rc.0 (and at least some earlier versions too)
Steps To Reproduce
https://codesandbox.io/s/suspense-context-test-case-6jlsq
The current behavior
In the example above, clicking on the "About" button puts the <Suspense> boundary into a suspended state. Clicking "Home" updates the context value, but the <Context.Consumer> callback is not called with this updated value. Therefore the page never navigates back to "Home".
Please note that Received context: home is not logged after the "Home" button is pressed.
The expected behavior
The <Context.Consumer> callback should be called with value 'home' when the value of the context is updated.
Please note that the problem does not occur if any of:
- the Suspense boundary is never suspended (uncomment the first line of
About function to verify).
useContext() is used in place of <Context.Consumer> (substitute <SwitchWithUseContext /> for <Switch />).
- the contents of
Switch function is inlined within the <Suspense> rather than in a separate component.
The last of these leads me to suspect that the problem may be related to #17356. In the example, <Context.Consumer> is within a Switch component. But the <Switch> element inside <Suspense> never changes - so it's effectively memoized. I wonder if this is why it doesn't receive context updates?
A
<Context.Consumer>callback inside a suspended<Suspense>boundary does not receive updates when context value changes.This issue was originally found with React Router (remix-run/react-router#7137) but can be reproduced with React alone.
React version: 16.13.1 or 17.0.0-rc.0 (and at least some earlier versions too)
Steps To Reproduce
https://codesandbox.io/s/suspense-context-test-case-6jlsq
The current behavior
In the example above, clicking on the "About" button puts the
<Suspense>boundary into a suspended state. Clicking "Home" updates the context value, but the<Context.Consumer>callback is not called with this updated value. Therefore the page never navigates back to "Home".Please note that
Received context: homeis not logged after the "Home" button is pressed.The expected behavior
The
<Context.Consumer>callback should be called with value'home'when the value of the context is updated.Please note that the problem does not occur if any of:
Aboutfunction to verify).useContext()is used in place of<Context.Consumer>(substitute<SwitchWithUseContext />for<Switch />).Switchfunction is inlined within the<Suspense>rather than in a separate component.The last of these leads me to suspect that the problem may be related to #17356. In the example,
<Context.Consumer>is within aSwitchcomponent. But the<Switch>element inside<Suspense>never changes - so it's effectively memoized. I wonder if this is why it doesn't receive context updates?