One topic I can say I commonly hear when discussing with fellow devs is the justification of using React’s Context for “holding” a value when you can:
- export it from a
- attached a global value on the
- define it as and environment variable and let your bundler get it from
These are all simple and clean (as in obvious) ways to keep global and constant values. By “global” I mean entire-application-global. Same for the “constant” notion, although, you could trigger an explicit re-rendering on the app when a setter function is called.
Bellow I will give an example of these two conditions slightly diverging and that’s when Context shows it’s usefulness. We are omitting props drilling, of course, assuming you’d like to avoid that, since you arrived at deciding between Context or globals.
Take the case of a range of colors for some elements. Let’s say a pallet of colors for a website featuring interior design.
For comparison I will tackle only this case of defining global value. Let us create a file where you’ll write the following.
Then import it in a component:
Finally, display your pallet.
And the visual output would be:
Everything works and looks nice. This is fine when the component tied to the colors is itself a singular element in the app.
Yet, once you need to render, the
ColoredBlocks component cannot be reused with other values (remember, prop passing is assumed not to be an option).
Many apps have context providers as a single, close to root wrapper around all the app. Be it React Router, Redux, Appolo Graphql, it’s likely you’ll see just one of the providers and lots of consumers arbitrarily spread throughout the code.
However, when actively reading the Context documentation you’ll see the first subtitle “Context provides a way to pass data through the component tree“. A few paragraphs down the page it writes “it will read the current context value from the closest matching
Provider above it in the tree“.
We know from a the datastructures 101 course that any subtree is a tree itself. React components are no different. That means we could have providers for several branches.
Let’s redefine the
ColoredBlocks component. I’ve defined the context in the same file, but you could easily have it elsewhere.
An leveraging it would like:
This produces the desired visual output:
It’s true, one would probably define the color values in a different module or config file, but it’ll only be passed to the
ColorsProvider and it won’t “litter” your application code.
That’s one of the advantages the Context API offers over global values. It’s the ability to work with the component tree. Any tree, therefore code (components) can be shared and reused, inside the same app and cross projects. It bring flexibility whilst sticking to a standard. This is part of React’s philosophy, to work with your hierarchy as much as possible. Actually, the mindset is a good practice for software development in general, and is loosely known as the Dependency Injection principle.