The below question relates to the following sections in the React Context documentation:
Disclaimer: Apologies for all the background information below. It provides context and will hopefully be helpful to future visitors.
What We Know
- Link 1
- The (default) context value is set to
themes.dark(an object that contains two properties:foregroundandbackground) - The default value is only ever used if there are no
Providersabove theConsumerin the component tree - In this case, there is a
Providerpresent in the top-level component (App) - This
Provider(App), passes down its ownstateas the context value - It is smart to keep the values provided by a
Providerequal in structure and type to the default context value (avoidsConsumersgetting confused) - Thus,
statein the top-level component (App) holds an object of the same format as the default context value:themes.light - Conclusion from the above: When a
Consumerreads the context, it readsApp's state - In other words, we are here using context to pass a parent (
App)statedeep down in the component tree, without having to pass it through every component in the middle - When state in the top-level component (
App) changes, it re-renders and a new value for state is provided to theConsumer - This way, the
Consumerreads the parent'sstate, via context - ...
- Moving on, we see in link 1 that a function to set
state(toggleTheme) is passed down the component tree as a normalprop - Thus, in link 1,
contextonly contains an object that readsstate - We are able to set state in the
Consumerby passing thesetStatefunction as a normalpropfrom theProvider's child, down through all the intermediate components, and in to theConsumer - Setting the
statein the top-level component (App), leads to a re-render of itself, which leads to a re-render of theProvider, which then passes the newAppstatevalue down to itsConsumervia context - As such, the
Consumeralways knowsApp's state, via context - In conclusion, the flow is:
- Parent's
stateis provided as context value to childConsumer(s) - Parent's
stateis updated by some child - Parent re-renders
Providersees that context value (App'sstate) has changed, and re-renders all itsConsumers with the new value
- Parent's
- The (default) context value is set to
- Link 2
- In link 2, we set
statein theConsumer, by passing thesetStatefunction within the context - This differs from link 1, where we relied on a normal
propto setstate
- In link 2, we set
Questions
We know from the docs that:
Every Context object comes with a Provider React component that allows consuming components to subscribe to context changes....
All consumers that are descendants of a Provider will re-render whenever the Provider’s value prop changes.
- Let's assume we use a normal variable in
Appas the context value. We know from the above quote that changing it leads to theProviderre-rendering. Why then, do we bother usingstateas the context value? What is the benefit of that, vs. just using any normal variable inApp? - Both the two approaches above allow us to update
state. Why is link 2 incorporating the function to updatestatewithinstateitself? Could we not just have it as a separatesetStatefunction, which is passed to theConsumervia context in an object that has two properties (one isstateand the other is the standalone function to updatestate)?