Why does useContext work without Context.Provider?
Asked Answered
L

2

8

Can you explain me why useContext() works for me if I don't wrap my components with Context.Provider? I just exported result of "createContext(someValues)" with predefined values and called useContext(exportedContext) in component and it works. Every tutorial tells me to wrap components. Has something changed in React?

Lampoon answered 25/4, 2022 at 19:34 Comment(6)
It works but you are given undefined as a value, I guess it's a compromise between DX and trying to keep the app without crashing in production.Handyman
what do you mean - undefined as a value? I can successfully read a values (predefined) from context via useContext hookLampoon
Oh, right, I was thinking only about createContext() with no default value, that gives undefined.Handyman
I don't think this has ever changed, it's just that using context without wrapping your component is kind of useless, you could just export a constant and import it elsewhere without using a context in the first place.Handyman
@JakubKotrs it is not useless. Think of this: context holds some values and initialised with the sensible defaults. Somewhere in your component tree you want those defaults to be used, so you just do useContext. And where you want them to dynamically change based on certain behaviour, you wrap that subtree in a Context.Provider that provides new value (overriding the default). Context in React is not just a state management mechanism. It is more of a dependency injection mechanism. If you want it to be a state store, then wrap your tree in a provider and boom now it is a state store.Albertalberta
@Albertalberta You right and I have used it this way as well since I made that comment.Handyman
T
11

All consumers that are descendants of a Provider will re-render whenever the Provider’s value prop changes. In other words, If you don't wrap your components with Context.Provider they won't get re-rendered when the someValues in createContext(someValues) changes. You will get the initial value that you set only in the first render.

Demo here

Toga answered 25/4, 2022 at 22:40 Comment(3)
Hey. Thank you for your answer. Are you sure about that? Because as I see, it doesn't re-render if I change context value. Only way to re-render is to put into context value state with method setState.Lampoon
Here is a demo example that I've prepared for you: codesandbox.io/s/react-context-provider-example-hl4e4f I hope that helps :)Toga
Great answer!, We need more quick examples like these when it comes to closing the gap between class & functional component differencesEurus
A
7

React.Context always worked this way. If a component is not wrapped in the Context.Provider it will receive the default value that was set when the context was created.

Provider's job is to override the default values, essentially providing dependency injection mechanism to React component tree.

Here is a good answer from React team: https://github.com/facebook/react/issues/17912

Albertalberta answered 21/3, 2023 at 0:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.