You make it sound like react is a dark box with a lot of magic behind the curtains, but I always found the react model very easy to reason about. Modifying state is explicit and is the only thing that can trigger a rerender. These rerenders can only happen down from where in the tree the state change happens.
That's an article listing the top 18 state management libraries for React.
18?!?
React devs can't even agree on a common development model for state, but you think it's explicit and very easy to reason about?
Folks don't adopt utility libraries for things that were already easy to reason about on their own. I'm glad you've found peace with React's basic notion of state, but it's a far cry from optimal. And the "state ecosystem" of React is a dumpster fire. Layers upon layers of madness that acolytes peer through and proclaim insight.
> These rerenders can only happen down from where in the tree the state change happens.
Yes, after it has DIFFED the whole tree to see where the changes occurred in the first place. Madness. Layers of utter madness.
React isn't a state manager and why should everyone be forced to use the one "blessed" manager?
Despite there being so many, only a handful (redux toolkit, jotai, zustand recoil, and mobx) see much real-world use and they are basically just 3 approaches (reducers, signals, and directed graphs) with varying levels of complexity and features.
> Yes, after it has DIFFED the whole tree to see where the changes occurred in the first place. Madness. Layers of utter madness.
Not true. It only needs to diff the leaves of the part that changed and some of those sub-trees can be skipped too if they are functionally pure (or uses shouldComponentUpdate). This is how they reduce complexity down from O(n^3) to something generally closer to O(n)
I’ve written a lot of react apps (first used it in a hackathon in 2014) and this list is really just fluff. hooks + context make all of these libraries pretty much unnecessary for most react apps as they are not that complex
I think the more glaring criticism is the lack of any unified component library. The amount of different Button implementations alone is astounding
I agree on both points. I used to quite like Redux but, between NextJS simplifying the page model and hooks/context being a lot easier for CRA-style apps, I just don't need them anymore for the sort of things I do.
The real kick to the shins is that React Server Components did a number on most component libraries, too. I've been forced to go to Tailwind (and DaisyUI, which is pretty nice) just so my stuff doesn't require 'use client' all over the place. The end result will be way better, it already is when you actually can get there, but right now it's annoying and awkward.
That was something that React Server Components definitely got backwards. The default state of the world before RSC was client components. If a mark is needed it should have been "use server" for the new style of components.
I don't mind that, because I think server components should be the default. They're better. But the profusion of CSS-in-JS solutions (which always seemed unwise to me) take it on the chin because of it.
> hooks + context make all of these libraries pretty much unnecessary for most react apps as they are not that complex
To be fair, context is not a state management tool [0], an article by acemarke, the Redux maintainer. It does work as a dependency injection tool and for many people, that's enough, but it's not a true state management tool.
React context is is just a way to bridge props deep down a component hierarchy. By combining it with an appropriate hook you can almost obtain the effect of a state manager like redux. There are limits to this however; being just a way to pass props it doesn't give you any fine control over reactivity
I did specify hooks + context, not just context. Hooks + context together can be cobbled together into an adequate state management solution for most apps, this article even agrees with me. So not sure what your point is lol
I just write my first fairly complex react app. As a mostly backend/tool Dev with good knowledge of functional programming I agree with this. I could solve almost any problem using hooks + context and memo. I briefly considered using Redux but I quickly realised that a few changes in certain components would take care of most of my state management problems
React is honestly how I used to write my code in jQuery too, for some pages that had a lot of state. Basically, just like in game dev, I had a render() function that I'd call at the end of the file that would re-render everything. The pattern itself is very easy to understand, re-rendering efficiently is the hard part, but for React users today, that's an implementation detail.
Hooks are also very interesting, they're basically functions that run at specific times, or that is to say, they're `f(...parameters, state)`. They hold state inside the function, sort of like a closure.
Indeed, seeing hooks as closures helped me to understand how they are use for state management. It's really a "poor man's object" with all the advantages of FP in terms of reasoning about state changes, lack of side effects etc.
What do you mean by "many?" While I like Relay, I've almost never seen Relay used in the wild. It's sad as it's quite an elegant concept; just as you define your props for your React component, you define your "props" coming from the server as well, through the GraphQL notation. I've been looking at ways to combine both concepts so that there is no client- or server-side state at all, it's all just state, from a cache that determines whether to refetch from the server or to keep the state local.
I agree that Relay CAN be simple, but it isn't for what we do. Have a look at this ReplyListContainer and its nested Relay logic. I didn't originally write this, but I can see what they were trying to do and how Relay made it difficult for them. Your thoughts are welcome, I won't judge you for being critical of our code and welcome any other Relay dev's opinions.
Relay tries to solve the problem of: let a component define its (server) data dependencies. It indeed does this with more magic. But it's not exactly the same problem and you can't really fault react for it. It's also a problem other frameworks don't try to solve.