-
Notifications
You must be signed in to change notification settings - Fork 47k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New Context Provider may block Old context propagation if children are constant #12551
Comments
This is a weakness in the old context API. While you're seeing the problem manifest when combined with the new context API, it's not specific to that. In general, distant children can have updates using the old context API blocked if more immediate children decline to rerender. More about the issue in the old context API docs: https://reactjs.org/docs/legacy-context.html#updating-context The usual way to solve this was to implement your own registration/observation system and send it through context. The context would contain a callback that consumers could use to register themselves, and then when the parent wanted to push a new update, it would send a signal to all registered consumers, which could then force the rerendering of their own children with Simply returning different values to |
This was actually encountered when using react-router; |
I'll tag as a bug although I'm not sure. Can you create a test case in My guess is that maybe a condition like this is also needed before bailouts here, here, and here. But I’m not sure. |
- Revert to previous context implementation that does not rely on the old context API to ensure both API’s can co-exist, related: facebook/react#12551 (comment) - Support `defaultValue` on select elements. - Fix getChildContext’s update phase invocation to happen after state has updated but before “render”.
I am just guessing, but I assume that this is using a similar bailout logic as Maybe this actually will be the right thing to do once the old context API is gone. |
I suggested a fix in the comment above. This probably won't be a priority for us but if you send a PR we with tests can take it. |
Should be fixed in React 16.4. |
Do you want to request a feature or report a bug?
Bug
What is the current behavior?
It seems that, if the children of a new-style
React.createContext()
contextProvider
are constant, theProvider
can block updates from old-stylethis.context
context providers from propagating tothis.context
consumers.This sandbox demonstrates the issue. Clicking the button with a number will correctly increment the
Root
'sstate
andcontext
, but the update is only propagated to theChild3
'scontext
(and its button) when the "Colors!" button is clicked, as it causes an update to thevalue
of the new-styleProvider
:https://codesandbox.io/s/ol4lpokpjy
Copy of the source code in the sandbox
What is the expected behavior?
Both old-style and new-style context updates should coexist.
Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?
16.3.1; also broken in 16.3.0.
This seems to only happen if the
children
of theProvider
are constant, which is what happens when the children are provided on the first and onlyReactDOM.render
call. IfChild1
is updated to directly use<Child2/>
instead of{this.props.children}
, the problem does not happen.This can also be a problem when using a production optimization that hoists constant elements outside the Component if the specified children are constant, which would even defeat the fix/workaround for the example above.
The text was updated successfully, but these errors were encountered: