DEV Community

Cover image for React State Management in 2024

React State Management in 2024

Hồng Phát on December 08, 2023

In my POV, React state management libraries can be divided into three groups: Reducer-based: requires dispatching actions to update a big centra...
Collapse
 
ghamadi profile image
Ghaleb • Edited

The only good thing Redux still has going for it is its Devtools, and that will never be a good enough reason for me to use it. It's the most used tool because it's the earliest robust tool and goes back to the days of class components.

Redux, and central state management in general, make needless globalization the go-to approach to share state, which can quickly turn into a nightmare.

I am convinced that the notion that "central stores are suitable for large projects" is the biggest sham in history. I know from experience that the opposite is more likely to be true.

Central stores are only good for bigger apps only when most state is global by definition. That's it. And I don't know many such use-cases.

Collapse
 
nguyenhongphat0 profile image
Hồng Phát

It looks like you and I had the same DX with Redux 😆

Collapse
 
boas19910115 profile image
Gongben

+1

Collapse
 
ichchkv profile image
Ivan Chichkov • Edited

If react offers a context and providers and a way to consume the context values using hooks, you must have really specific needs to go and search for libraries. I believe 90% of projects don't.
So, use your common senses, as first step, then plan further.

Collapse
 
ivan_jrmc profile image
Ivan Jeremic

The need is most often the re-rendering the whole app problem. It is better to re-render a few components than the whole tree, that's also the reason why you should work with multiple contexts and not just with one which however becomes hard to manage.

Collapse
 
ichchkv profile image
Ivan Chichkov

Yes, but you can have as many context providers as you need, as atomic as you need them to be. Provide them as hooks and use them. You'll avoid the dependency to any 3rd party libs and go with pure react. You'll have full control over what you provide and the scope you consume your context in.
Never understood overcomplicating our own work with additional libs if we can achieve our goals with the tools at hand.
There should be real need to solve a problem when you make a decision and first thing is to try to write some code instead jumping on libs wagon ... Libs are good think but they are created to solve problems where they exist.

Thread Thread
 
silverium profile image
Soldeplata Saketos

but the moment your app needs a global context provider (let's say for global notifications), then the app is screwed with multiple rerenders with Context

Thread Thread
 
ichchkv profile image
Ivan Chichkov

It is getting interesting .. and why you think so?
It is up to you when you re-render and what, no? And why any change in whatever of your context hooks will cause re-render of anything you do not change?

Thread Thread
 
ivan_jrmc profile image
Ivan Jeremic

It is not as easy as you might think, there is a reason why the number one rule to learn is that Context alone is not a state management solution.

Thread Thread
 
silverium profile image
Soldeplata Saketos

Well, I think there is a misunderstanding of what is a re-render and what is a re-computation.

A re-computation is when the current component is called again (as a function) and all logic inside is being triggered.
Example:

import * as React from "react";

let externalCounter = 1;
const LoggingComponent = () => {
  const [internalCounter, setInternalCounter] = React.useState(1);
  const [, forceRender] = React.useState(1);
  externalCounter++;
  console.log(
    `current internalCounter is ${internalCounter} and external is ${externalCounter}`
  );
  return (
    <>
      <button onClick={() => setInternalCounter((p) => p + 1)}>
        {internalCounter}
      </button>
      <button onClick={() => forceRender((p) => p + 1)}>Force recompute</button>
    </>
  );
};
export default LoggingComponent;
Enter fullscreen mode Exit fullscreen mode

You will see that the LogginComponent is re-computed and the console log will show that the externalCounter is increasing every time you click the "Force recompute" button. Something similar happens with the useReducer

Thread Thread
 
ichchkv profile image
Ivan Chichkov

Hmm, shall you give a thought about what it will be for moderately sized and complex application to get dependent on some libraries that are perfect, but not actually needed?
In summary, React's Context API, when used judiciously with React Hooks, provides a more efficient way to manage state and control rendering behavior in a React application. It offers a simpler and often sufficient alternative to more complex state management libraries for many use cases, especially in moderately sized applications, as I mentioned above.
So, instead of 'first rules' we better use our common senses' as rules often are subjective to the use case or the user.

Thread Thread
 
ivan_jrmc profile image
Ivan Jeremic

Do whatever you believe just keep in mind that context is not a state manager.

Thread Thread
 
silverium profile image
Soldeplata Saketos

I would say that a "moderately sized" app is one which does not have:

  • full page overlays, pages with entities (models, data, whatever you call it) that need to be kept in memory while client side navigating to other pages
  • actions that trigger changes that affect multiple entities
  • more than 20 pages

When you start to have complications like:

  • user state management
  • shopping carts
  • messaging
  • global banners, popups, etc
  • dynamic theming, translations, and global complex stuff Then it's better to rely in Redux, with RTK, which will provide a super nice DX with all actions centralized, visible state tree, independent slices, re-select, etc
Collapse
 
ivan_jrmc profile image
Ivan Jeremic

I know how context works, and I also wrote context like you do since 2019, you are misunderstanding a few thing and you think you simplifying while in reality you write more code. I bet if you show me a project where you do this I will find tons of unessecary re-renders.

Collapse
 
adaptive-shield-matrix profile image
Adaptive Shield Matrix • Edited

Atom-based Libraries

  • Are the best approach, because you do not have to have a global state and can select and just use different state parts (atoms) that you need.
  • It blows any other state management solution out of the way by provided developer experience and ease of use.

Atom-based Libraries / Weaknesses

  • I would not list DevTools as a downside, since no global state management solution (including react context hooks) allows you to
  • all listed waeknesses are about recoil
  • Jotai has no weaknesses

Jotai

  • ask anyone, who tried different/all state managers, and everyone will tell you that Jotai is the best
  • DevTools: jotai provides an api to see/log state updates
  • has best and most helpful community/support on github

Generel

20Kb difference is huge, who says it is not?
Only one who can that are people using Nextjs that ships 200kb of JS even in a simple hello world example -> RIP all old/cheap smartphone mobile users (and all users of your app/website in third world countries).

I have written an article, where I touched on state management in react
dev.to/adaptive-shield-matrix/reac...
TLDR: no one should use react build-in state managers. Pick one library - Jotai (recommended) or Zustand and use it exclusively.

Here is some prior art comparing react state managers, about a year ago
frontendmastery.com/posts/the-new-...

Collapse
 
brense profile image
Rense Bakker

I'm not even sure why recoil still exists tbh... They were really good at SEO for a long time, thats for sure, but that discouraged a lot of people from using atoms, because they would stumble upon recoil first, before jotai, when they searched for atom state management. Luckily that's no longer the case, but we can see that a lot of people still asociate atoms with recoil :(

Collapse
 
pengeszikra profile image
Peter Vivo

My personal solution of state management is useReducer which is a ligthweight replacer of redux. A small 100LOC code npm module written in typescript.
(react-state-factory)npmjs.com/package/react-state-factory[dev.to/pengeszikra/simplify-your-r...]
I give a typescript helper for state handling user can define own - even complex state type - and pass to useReducer.
This type of state is not mandatory use at global statate level, and boiler plate near easy as useState.

Collapse
 
silverium profile image
Soldeplata Saketos

The only problem with this approach (if any) is that the state is updated in every single action, triggering a re-computation of the component, which might lead to re-assignments of any other logic inside the component, and could potentially lead to re-renders if the devs are not using useCallback or useMemo or even memo depending on the case.

So, for this to properly work, you need the devs in your team to be aware of the pitfalls to be avoided.
Example of bad implementation:

const Parent = () =>{
   const [state, dispatch] = useReducer(someReducer, null, { a: 1, b:1, c:1});

  const someComputedValue = a  / c;

  return <div>
                <OtherComponent value={someComputedValue} />
                <button onClick={()=> dispatch({ type: "set_b", payload: 42})}> set b to 42</button>
           </div>
}
Enter fullscreen mode Exit fullscreen mode

As you can see, in this example, OtherComponent would be re-rendered even if values a or c were not modified.

Collapse
 
karanborana1210 profile image
karanborana1210 • Edited

Great article @nguyenhongphat0 . I recently found Jotai, and I am blown away by it's simplicity and DX. But, I am still not sure what will be the best practices for using Jotai in a big project where there is big state object to manage. I haven't got any example of such. If you have any idea on this, please write another article on this, will be of great help 🙌. Thanks!

Collapse
 
nguyenhongphat0 profile image
Hồng Phát

Thank you for your compliment, I really appreciate it! I would love to share my specific experience with Jotai and tips that I found useful in another blog. Stay tuned 🤗

Collapse
 
karanborana1210 profile image
karanborana1210

Sure @nguyenhongphat0 . I have been using Jotai for a while now, but only for small projects as of now. Haven't been able to decode the best practice to use it in large projects. Will be waiting for your article.

Collapse
 
fosteman profile image
Timothy Fosteman

Good. Always used proxy-based MobX singletons with Typescript. Best combo

Collapse
 
daliskafroyan profile image
Royan Daliska

MobX is awesome, I recently use legend state as an alternative. It has everything mobx provide but has less boilerplate

Collapse
 
merri profile image
Vesa Piittinen

Signals.

Although React is so 2018 that you might want to consider something else. Like, something that actually has been designed to work great with signals.

Collapse
 
christian_go3 profile image
Christian GO

Learned something new, thanks for sharing!

Collapse
 
funnypan profile image
panfan

zustand

Collapse
 
fantasticsoul profile image
幻魂

try helux github.com/heluxjs/helux
About
A state engine integrates atom, signal, derive, watch and dep tracking, supports fine-grained responsive updates, it is compatible with all react like libs (including React 18)

Collapse
 
raibtoffoletto profile image
Raí B. Toffoletto

I don't feel if you need a library in 2024. React manages state fine if you know how to use all of its hooks. Also it is well complemented with SWR or ReactQuery

Collapse
 
mzvonar profile image
Martin Zvonar

I’m so glad to see Jotai as your top choice. I find it so simple and elegant.
I wanted to give recoil a try for a new small project, but I saw it’s still experimental and hasn’t been updated for a year. So I grabbed Jotai again. I wanted to check whether there is some newer better approach and found your article :) My soul restd assured :)
How do you solve a use case when you need to do a derived atom but need a dynamic variable (e.g. categoryId)? Creating the atom dynamically inside the component, memoizing it and using it right away seems a bit clunky. I wonder if there’s a better approach…

Collapse
 
mfp22 profile image
Mike Pearson

How would you categorize StateAdapt?

Collapse
 
mfp22 profile image
Mike Pearson
Collapse
 
nguyenhongphat0 profile image
Hồng Phát

This is the first time I heard about this library! But it looks promising with that RxJS support. Although it doesn't perfectly fit into the Reducer-based group, the way actions show up in Redux DevTools when you use StateAdapt's API hints that it uses a reducer-based approach under the hood.

Thread Thread
 
mfp22 profile image
Mike Pearson

Yep, it was originally implemented as a reducer within a Redux-like library.

Collapse
 
idleman profile image
idleman

Typescript is an anti pattern. It is something that sounds good, but is bad. So having that in the list actually make this article lose credibility.

Redux is a good start for most people because it enforce you as developer too think more about how you structure your app and its state than the rest. It is basically event sourcing which is an extreme powerful design pattern.

Collapse
 
nguyenhongphat0 profile image
Hồng Phát

I believe that everyone has a unique point of view and developer experience. You might prefer JavaScript over TypeScript, but I would pick TypeScript most of the time. Typing things initially took more time in my projects, but having IDE autocomplete saved me much time later (and that was just one of many TypeScript's awesomeness) 😎

Collapse
 
idleman profile image
idleman

TypeScript does not have types, it has annotations. And yes, it is huge difference. Types you can trust, always, annotations never. If you want types, use webassembly.

And no, TS do not save time. Type or dont type research paper some year ago showed clearly TS cause more bugs and cause longer development times.

Thread Thread
 
boredcity profile image
boredcity

My experience is TS really can hurt initial development time but saves a lot of it when you start adding/removing features and refactoring (usually that's at least 75% of time for a mature product). Annotations can be trusted majority of the time with a sensible config (although I do miss proper types Dart has) and the only alternative I see is JSDoc which is more verbose and has all the same drawbacks.

Thread Thread
 
idleman profile image
idleman • Edited

That is the issue. People, like yourself think annotations can be trusted. As the application and the code grows, bugs tends be introduced because the developer believe he/she can trust the all the annotations. That is what the research paper I mention for you earlier proofs. The more you trust TS, the more problems will come.

Overtime will you learn you code against an interface all the time. Some programmers learn this experience after a couple of years, some it takes 10 years - others understand it first after 20 years. But the faster you learn it, does suddenly the "typing" not make so much sense anymore. The only reason why it was invented in the first place was because of memory alignment together with CPU instructions. Not to help developers to create robust and large applications.

Thread Thread
 
boredcity profile image
boredcity

hmm, the only paper with a name similar to the one you mentioned is this one — and it's definitely pro-Typescript. Could you please share a link to whatever you're using as a basis for your statements, please?

Thread Thread
 
idleman profile image
idleman • Edited

arxiv.org/abs/2203.11115

Analyze the numbers a little bit and you see the problem.

Thread Thread
 
boredcity profile image
boredcity

First of all, thank you for the link! But I'm not sure the paper supports what you're saying, tbh:

The analysis indicates that TS apps exhibit significantly better code quality and understandability than JS apps. Contrary to expectations, however, bug proneness and bug resolution time of our TS sample were not significantly lower than for JS: mean bug fix commit ratio was more than 60% larger (0.126 vs. 0.206), and TS projects needed on average more than an additional day to fix bugs (31.86 vs. 33.04 days).

They actually mention that one of the explanations might be Typescript being chosen for more complex projects. There's also a long section on threats to validity in the paper with some valid concerns. By the way, I'm not 100% convinced if the metrics used make a lot of sense for anything outside open source development with its very specific set of problems and behaviors (but that last one is only my personal opinion, ofc).

On "All other studies are bought by Microsoft" theory (which seems helpful to cement your "I have research behind my back - you don't" argument), paper itself mentions that it contradicts some pre-existing finding. Putting that aside, companies (like Google or Meta, for example) are using Flow / Closure compiler (that have ~ the same perks and drawbacks TS does in regards to type system) without too actively pushing them to anyone — and most of their decisions tend to be data-driven.

All in all, I honestly think it's sensible to question Typescript's usefulness (especially in the light of type anotations proposal) but it would require some better arguments.

Thread Thread
 
idleman profile image
idleman • Edited

It 100% supports what I am saying, you just lack the knowledge to understand it.

significantly better code quality and understandability

It is what developers reports and the author just forward. In other words, it is what developers generally feel, not fact. If it really were true, it should've support in lower bugs and faster development speed heavily for TS vs JS, but that is not the case. That is why you must analyze the numbers.

not significantly lower

Having around ~10% larger codebase, several more commits in average and multiple more days to fix a bug is a lot compared to the alternative to not use it at all. So yes, understand the numbers before you speak and compare every single thing vs JS. The learning curve, the complexity, time on bugs vs features, the extra complexity, the unsafe future (it will very low chance it will be added to the ECMAScript, read the latest meetings notes in the type annotations proposal). TS is just extra risk everywhere.

They actually mention that one of the explanations might be Typescript being chosen for more complex projects.

Sure, or it could be reverse. But the truth is probably either. The realistic possibility is that people who love TS, use TS and people who prefer JS, use JS. And with same skill, JS wins.

PS. Do you know that large companies such as Meta and Google have enough money so they can hire really good developers? Do I need to tell you less experienced and average developers are more productive in JavaScript? Have your ever coach a bunch of junior developers? I doubt you will have the same opinion after 1 year if you did.

Thread Thread
 
michaeltharrington profile image
Michael Tharrington

Heyo! Community Manager speaking — please remember to keep it friendly here!

There's no need for terse accusations like "you just lack the knowledge to understand it" or "understand the numbers before you speak" — if this is your feeling that's fine, but your tone here feels very gatekeeperly and there must be friendlier ways to word this. Disagreements are bound to arise, but remember to follow our Code of Conduct and treat folks with respect.

Thread Thread
 
boredcity profile image
boredcity

Let me make these 3 points and I promise this is my last message in this thread 😅:

1) if the question was whether junior developers should use Typescript for small projects, I'd 100% agree that they probably shouldn't 🙂 That's not how you framed it, though.

2) As an ex-Meta Sr Frontend dev I can vouch for people there not being smarter-than-everyone demigods (well, I sure am not 😅); to make things worse more than a few devs contributing to frontend code have very little experience with JS, TS or React (writing PHP-like Hack or Python code day to day) 🙂

3) I have several years of experience teaching HTML, CSS and JavaScript to complete beginners; I would never suggest they learn TS instead of JS, ofc. But I also taught a course on Typescript to middle/senor developers and most of them found it useful 🤷‍♂️

All in all, as always, "use the right tool for the right job". Small projects (especially by inexperienced teams) likely don't need TS but larger ones might.

 
idleman profile image
Comment marked as low quality/non-constructive by the community. View Code of Conduct
idleman

There was nothing disrespectful in that answer. It is however disrespectful to me as person you just assume I mean any disrespect/harm by telling the truth. Would write it again if needed. And no, you have no authority to decide if something is disrepectful or not. The only thing you can do is to ban my account, but i don't give a fuck if you are so fucking disrespectful. I don't want to be part of this woke-toxic communitiy anyway.

Collapse
 
mfp22 profile image
Mike Pearson • Edited

I doubt you've ever tried TypeScript for more than a week. The reason you like Redux is also the same reason some people like TypeScript. And no, it's the opposite of what you say: Everyone I knew when TypeScript got big thought TypeScript sounded terrible. Then after using it fell in love with it. I will personally never go back. I couldn't.

Collapse
 
idleman profile image
idleman

The reason why TS is an anti pattern come from a management perspective. It cause more bugs and slower development speed. No benefit at all from a business point of view. All objective research papers show it, such as type or dont type paper. Only paid research from Microsoft say it is good.

You can still love it though, but just know the marketing for TS is a lie.

Thread Thread
 
mfp22 profile image
Mike Pearson

It prevents bugs and increases development speed. There's no need to specify "from business point of view" because that's the default point of view.

Answer honestly: Have you ever used TypeScript for more than a week on a typical application?

Thread Thread
 
idleman profile image
idleman

False. Every research that is objective (large and not paid by Microsoft) show TS is counter-productive if you aim for high producivity. All the marketing is a complete lie. TS is worst, it has no types, cause more bugs, longer learning curve, has lower development speed.

TS sucks in every way except it cause some developers find the code more readable than regular JS, but that does not mean anything if the end product is more bugs and lower producivity.

Sure, you don't agree with me, but I have research behind my back- you don't.

Thread Thread
 
pengeszikra profile image
Peter Vivo

My personal research show TS is really helpful even at start phase of hobby project. But also help a lot, when I start transform my real world complex JS react application to TS based one, and even at phase of small amount ts code parts give a great guidance which is improve our development speed a lot.

I know until we don't familiar the use of generic in TS it is harder, but after the whole development process will be much cleaner.

Until I try TS personaly I hated, because with JS I can write code much flexibile, but at that moment I did not work with generals.

TS drawback is the use of generator functions, but correctly declared generator function type, whic can be any amount of yield pont is really crazy things, my advice when we would like to use generator function then best way to forget the TS. But who is using generator function?

Collapse
 
karanborana1210 profile image
karanborana1210

Hello @nguyenhongphat0 , want to discuss something about Jotai and it's using strategy. Possible to connect?

Collapse
 
17lingshan profile image
17LingShan

I use Mobx when I'm working alone on a project. ❤

Collapse
 
hckhanh profile image
Khánh Hoàng