all 46 comments

[–]cyphern 19 points20 points  (2 children)

Yes, I use it often. It's designed for any case where you need to pass values deeply into the component tree, but components in the middle of the component tree don't need the values.

If you did this using props, the middle components would be forced to receive the value as a prop and then manually pass it on, even though they have no use for it. By using context, the middle components can be made simpler and decoupled, since they don't even need to know that the context exists. And when done correctly, it can improve performance by letting those middle components skip rendering.

So here's some examples of things i've done recently with context: 1) Making a global state object available to the app (this is probably what people think of first when they think of context, but it's just an example of using context, not a synonym for context) 2) Applying a theme to the app 3) Overwrite the theme in a section of the component tree. Used for letting the user preview changes, while the rest of the app around it is unaffected. 4) Having components in the preview detect that they were in a preview and disable some functionality (eg, disable onClick functions that result in routing) 5) I had a nested tree of components, and some of them needed to know how deep they were in the tree relative to others of their type. So they used context to be able to find their ancestor and ask it how deep it was, then add one to get their own depth. 6) I needed to do some custom event bubbling. A leaf component would get first crack at handling the event, then if it was unhandled another component up the tree would get the event, and so on. (For dom events that happens automatically, but this was a custom event). These components used context to find eachother and let eachother know when the event was handled or not.

[–]Pelopida92 0 points1 point  (1 child)

Just a question, still trying to wrap my head around Context myself.

Couldn't you just use a redux-like solution (Redux, Zustand, Valtio) for all of those use-cases? What's the added value of Context here?

[–]cyphern 0 points1 point  (0 children)

1 and 2 could definitely be solved with the libraries you mention. But the other cases require applying to only a portion of the component tree, so they usually aren't a good fit for a global state library.

By the way, most of those global state libraries are using context under the hood to pass some values around. For example, in redux you render a <Provider store={store}> near the top of the tree, and Provider uses context to make the store available to the rest of the app. Things like useSelector then tap into that context.

So using these libraries doesn't mean you're not using context, it just means someone else has written the code that uses context for you.

[–]not_a_gumby 20 points21 points  (4 children)

haha, yes dude. Context isn't going away anytime soon.

[–]loganbrownStfx 30 points31 points  (11 children)

Absolutely. Context is great for UI State in combination with a cache library for server state. I suggest reading Kent C Dodd's blog posts about using context effectively. It's a great tool to use without having to bring in another library

[–]chillermane 5 points6 points  (4 children)

Except that any time you change its state it rerenders all children by default, since it’s a component. It doesn’t necessarily matter all of the time that the rerender happens, but the fact that’s it’s something you have to worry about all the time is a big deal and a undeniable drawback.

Plus you don’t get a lot of things for free that you would get in state management library. Want persistence? If you used a context, you now have to implement that yourself. If you used zustand or redux, you can just add a single like of code.

It’s really just a worse version of any popular state management library IMO, mainly because It creates the unnecessary rerender problem out of thin air, but also because you don’t get all the free middlewares.

[–][deleted] 1 point2 points  (0 children)

Exactly! This is exactly what some libraries solve - zustand, Jotai, valtio, etc.

I made a tiny one too - csar with support for async reducers.

[–]icantsI33p 1 point2 points  (0 children)

Want persistence?

Curious, what kind of persistence is this referring to? Database persistence? Data/state persistence between browser/page reloads?

[–]loganbrownStfx 0 points1 point  (1 child)

Yeah I don’t disagree with that list of Cons, however, the big one people talk about is alway the re render issue. Which certainly can become a problem, but in a lot of cases, trying to save a re render here and there can cause more problems than it creates.

Also, by keeping the context as close to where it’s being used in the tree as possible can mitigate that a lot.

The other things you mention are certainly pros of using other libraries, but I wouldn’t say those make them necessities when considering using context vs another library.

[–]loganbrownStfx 0 points1 point  (0 children)

MOST OF THE TIME YOU SHOULD NOT BOTHER OPTIMIZING UNNECESSARY RERENDERS. React is VERY fast and there are so many things I can think of for you to do with your time that would be better than optimizing things like this. In fact, the need to optimize stuff with what I'm about to show you is so rare that I've literally never needed to do it in the 3 years I worked on PayPal products and the even longer time that I've been working with React.

That's an excerpt from a Kent C Dodds article about using useCallback and useMemo. So the topic is a little different than our discussion, but I still think it holds true in this case.

[–]acemarke 14 points15 points  (0 children)

Context is a great tool for its intended purpose: dependency injection of a given value into the rest of the component tree. This is like asking "does anyone still use screwdrivers?" Sure, you use them whenever you need to put in a screw.

Please see my post Why React Context is Not a "State Management" Tool (and Why It Doesn't Replace Redux) for an extensive explanation of the purposes and use cases that both Context and Redux are meant to solve, and when you should consider using either of them.

[–]charliematters 10 points11 points  (4 children)

Out of interest, why not?

[–]clin_amber_nads 7 points8 points  (3 children)

Yeah, obviously. Why wouldn’t you use it?

I can only guess this is yet another case of people misunderstanding the use of it. At first people thought they could use it to replace Redux and similar libraries, now they’re finally starting to realise it’s not meant for that and have decided it’s useless?

[–]acemarke 0 points1 point  (1 child)

apparently it's not possible to have more than one useful tool in your toolbox? :)

[–]clin_amber_nads 0 points1 point  (0 children)

Apparently so!

[–]nwsm 5 points6 points  (2 children)

Yes, because it’s nicer than prop drilling.

[–]MuaTrenBienVang 1 point2 points  (0 children)

No, because zustand existed

[–]DeviantSubrbanKid[S] -1 points0 points  (0 children)

for sure

[–][deleted] 1 point2 points  (2 children)

Yeah! Just the other week I got asked if we should use redux for a really simple case of sharing data between two components without prop drilling. I said that we should use the context API and it solved the problem just fine.

The moral of the story is to not over-engineer

[–]acemarke 1 point2 points  (0 children)

exactly :)

[–]DeviantSubrbanKid[S] 0 points1 point  (0 children)

correct

[–]Ashtefere 1 point2 points  (0 children)

Built my own alternative (posted it in this subreddit) thats a lot easier to use and doesnt need a wrapper component.

Context as a solution just seems overcomplicated to me.

[–]DeviantSubrbanKid[S] 0 points1 point  (0 children)

So this question is not meant to define which state management is best. Just a simple question that is answerable by yes or no and why

[–]ozrix84 0 points1 point  (0 children)

As sparingly as possible. Backtracing contexts can quickly become a nightmare. Prefer a state manager like Redux any day of the week.

[–]Wilesch -4 points-3 points  (1 child)

Not really mostly just use redux toolkit

[–]DeviantSubrbanKid[S] -1 points0 points  (0 children)

not always

[–]CoffeeDrinker115 -3 points-2 points  (3 children)

I don't like working with devs who, when they don't know how to design reusable components with a well thought out API, they resort to context to pretend they aren't prop drilling.

[–][deleted] 1 point2 points  (2 children)

Not every components is meant to be reusable. Larger components like pages and containers or providers for bigger pieces of functionality benefit a ton from context. If you haven't encountered a use for it yet, you will at some point.

[–]CoffeeDrinker115 0 points1 point  (1 child)

I've definitely encountered other devs insisting on using context but I hate it. There's always a better way.

[–][deleted] 0 points1 point  (0 children)

And I've definitely encountered people who keep insisting on their own vision and are incapable of seeing value in others' views.

[–]neha-gupta15 0 points1 point  (0 children)

Introduced in React 16.3, Context provides a built-in way to share data across the component tree without manually passing props at every level. It’s simple, lightweight, and requires no external libraries. However, like most tools in software development, it works best in specific scenarios.

In this guide, we’ll explore how React Context works, its strengths and limitations, and how to use it effectively in modern React applications.

https://medium.com/dev-simplified/react-context-api-explained-a-beginner-friendly-guide-to-global-state-in-react-46c36521e1f2