In my POV, React state management libraries can be divided into three groups:
Reducer-based: requires dispatching actions to update a big centra...
For further actions, you may consider blocking this person and/or reporting abuse
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.
It looks like you and I had the same DX with Redux 😆
+1
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.
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.
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.
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.
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
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?
Atom-based Libraries
Atom-based Libraries / Weaknesses
Jotai
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-...
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 :(
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.
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
useCallbackoruseMemoor evenmemodepending 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:
As you can see, in this example,
OtherComponentwould be re-rendered even if valuesaorcwere not modified.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!
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 🤗
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.
Good. Always used proxy-based MobX singletons with Typescript. Best combo
MobX is awesome, I recently use legend state as an alternative. It has everything mobx provide but has less boilerplate
zustand
Learned something new, thanks for sharing!
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…
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
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)
How would you categorize StateAdapt?
state-adapt.github.io/react
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.
Yep, it was originally implemented as a reducer within a Redux-like library.
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.
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) 😎
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.
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.
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.
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?
Hello @nguyenhongphat0 , want to discuss something about Jotai and it's using strategy. Possible to connect?
I use Mobx when I'm working alone on a project. ❤
Did you try nanostores? github.com/nanostores/nanostores @nguyenhongphat0