Description
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?