6 ms·
If any react noobs are reading this, the best React state management setup for you is Redux+Immer. After some setup, it's easy to use, and the docs are very goo
by IceHegel 6y ago
If any react noobs are reading this, the best React state management setup for you is Redux+Immer. After some setup, it's easy to use, and the docs are very good and up to date.
When I was learning React, I kept putting off Redux because youtube said it was complicated and you didn't need it after useContext. Big mistake. Our app became more complicated because our state management(useState/useContext) was so simple. Switching to Redux dramatically simplified our most complicated components.
Also, the Redux dev tools extension is a game changer. It lets you see every state change, in order, with traces and diffs.
https://github.com/zalmoxisus/redux-devtools-extension https://github.com/zalmoxisus/redux-devtools-extension
Pros can obviously make up their own mind. I’ve tried Mobx and the tooling just wasn’t there, but I hear their diffing algos are good.
- acemarke 6y agoTo be clear, we now specifically teach that our official Redux Toolkit package is the standard approach for writing Redux logic [0]. RTK uses Immer internally by default [1], and I actually just wrote a brand new "Writing Reducers with Immer" usage guide page yesterday [2]. All that said, this new "React Community Tools" site isn't intended to specifically plug Redux or recommend it instead of other tools. I want it to be a catalog and informational site that helps people understand what tools are out there and what problems they solve, so that they can make decisions about what tools to use based on their own needs and applications. I just happened to write a Redux page first because that's what I know about, and I wanted at least one draft page up there so that we can nail down what some of the content structure for these pages should look like and use that as a basis for getting people to contribute pages for other tools. [0] https://redux.js.org/tutorials/essentials/part-2-app-structure https://redux.js.org/tutorials/essentials/part-2-app-structu... [1] https://redux.js.org/tutorials/fundamentals/part-8-modern-redux#immutable-updates-with-immer https://redux.js.org/tutorials/fundamentals/part-8-modern-re... [2] https://redux-toolkit.js.org/usage/immer-reducers https://redux-toolkit.js.org/usage/immer-reducers
- arvigeus 6y agoI managed to replicate Redux Toolkit api with context and hooks. Still, would not recommend it over Redux for performance reasons.
- PragmaticPulp 6y agoGood place to start. Most important for beginners is to pick one state management solution and learn it quickly. Don’t waste time touring all of the options or trying everything. Pick one, learn it well, and get it going. You can evaluate alternatives after you understand the basics of one system.
- christiansakai 6y agoWhy do we need Immer? Can't we just do our object copying ourselves? It seems using Immer it can break dev's intuition about pass by reference and performance.
- acemarke 6y agoYou don't _need_ Immer. But: - Writing immutable update logic by hand is really hard to do correctly and hard to read - Accidental mutations have historically been the number one cause of bugs in Redux apps Immer eliminates accidental mutations, and makes it _way_ easier to write and read code that does correct immutable updates. So, we now recommend Immer as the right way to do immutable updates in Redux [0], and Redux Toolkit uses it by default [1]. Agreed that there is absolutely a learning curve aspect here - you need to know why and how to write immutable updates by hand to really appreciate what Immer is doing for you, which is why I've repeatedly highlighted that information in our docs [2]. [0] https://redux.js.org/style-guide/style-guide#use-immer-for-writing-immutable-updates https://redux.js.org/style-guide/style-guide#use-immer-for-w... [1] https://redux.js.org/tutorials/fundamentals/part-8-modern-redux#immutable-updates-with-immer https://redux.js.org/tutorials/fundamentals/part-8-modern-re... [2] https://redux-toolkit.js.org/usage/immer-reducers https://redux-toolkit.js.org/usage/immer-reducers
- pgsandstrom 6y agoMaybe Im missing something, but why not simple do a deep clone of the state object and then modify the deep clone?
- acemarke 6y agoA deep clone is _not_ what you want here. A correct immutable update is better described as a "nested shallow clone", where you copy each specific level of nesting from the root down to the value(s) you actually want to change. A deep clone would result in unnecessarily copying a bunch of extra objects and arrays that aren't relevant, so that's a waste of cycles. On top of that, the React ecosystem (and React-Redux in particular) relies on reference comparisons to determine if data has changed. If you copy objects that didn't actually get updated, it can cause a lot of components to re-render when they really shouldn't have. For more details see: - Dave Ceddia's "Complete Guide to Immutability in React and Redux": https://daveceddia.com/react-redux-immutability-guide/ https://daveceddia.com/react-redux-immutability-guide/ - The Redux docs page on "Immutable Update Patterns": https://redux.js.org/recipes/structuring-reducers/immutable-update-patterns https://redux.js.org/recipes/structuring-reducers/immutable-... - The Redux FAQ entry on deep cloning: https://redux.js.org/faq/performance#do-i-have-to-deep-clone-my-state-in-a-reducer-isnt-copying-my-state-going-to-be-slow https://redux.js.org/faq/performance#do-i-have-to-deep-clone... - The Redux FAQ page on immutability: https://redux.js.org/faq/immutable-data https://redux.js.org/faq/immutable-data
- jeswin 6y ago> If any react noobs are reading this, the best React state management setup for you is Redux+Immer. React noobs should just stick to React's own useState and useContext hooks. There are issues with it, but it's not as bad. Here's what Pete Hunt from the original React team said last week: "Literally never ever use Redux on a new project under any circumstances. Even if it’s what the team knows." [1] 1: https://twitter.com/floydophone/status/1365824299060273153?s=19 https://twitter.com/floydophone/status/1365824299060273153?s...
- acemarke 6y agoI pressed Pete on what he actually meant by that in the replies [0]. Eventually he listed some specific concerns: - The React ecosystem has fragmentation because there's many ways to do things, and he feels someone needs to start narrowing down suggestions to reduce confusion. - There was an article going around on "Why I'll Never Use React for Enterprise Apps Again", and half of the problems listed in the article were about Redux and React ecosystem related issues instead of React itself, so Pete's upset about that - Pete feels opinionated data fetching tools and explicit state machines solve some use cases better - Pete thinks it's too hard to dynamically code-split Redux logic So, those are valid technical points that can be discussed in detail. But those are also a very far cry from "NEVER EVER USE REDUX!", and I'm really not sure how you jump from "one article said they had trouble migrating their code from `connect` to hooks and they aren't happy with Redux-Saga" to "NEVER USE REDUX" either. I actually pointed out that we have a new upcoming "RTK Query" API that's in alpha right now [2] that drastically simplifies data fetching and caching for Redux, and Pete said later in that thread he thought it looked impressive. He also said he appreciates the work put into Redux Toolkit and our docs updates. So yeah, Pete said that, but as usual there's a lot more nuance in the later discussion that should be highlighted rather than the clickbait-y initial tweet. [0] https://twitter.com/acemarke/status/1365824897210064897 https://twitter.com/acemarke/status/1365824897210064897 [1] https://betterprogramming.pub/i-almost-got-fired-for-choosing-react-in-our-enterprise-app-846ea840841c https://betterprogramming.pub/i-almost-got-fired-for-choosin... [2] https://rtk-query-docs.netlify.app https://rtk-query-docs.netlify.app
- dsego 6y agoWhat about something like zustand? https://zustand.surge.sh/ https://zustand.surge.sh/
- boredpandas777 6y ago<<It lets you see every state change, in order, >> In general, if we use any async APIs in your JS that modify shared state the order will consist of an interleaving of all events, including from timers (macrotasks), DOM events (macrotasks), resolved and finalized promises (microtasks) and DOM APIs like IntersectionObserver (microtask), IDB et al, along with synchronous calls (including any recursive calls) so looking at things in order does not mean anything in a complex UI with lots of interleaved events if you cannot filter by a named action (the action that caused a certain chain of events, which otherwise will be displayed intermingled with all other events from other actions) you can't really follow the data and control flow of your app. So order only matters in debugging and comprehension if you can filter by action. Another thing we should care about is domain driven design and domain aggregates for your state store to make sure that only one aggregate root is responsible for a given part of state. If more than one chain of events (more than one named action) modify the same part of state then trying to comprehend the relationship between state and action becomes too complicated and you lose consistency guarantee as a result (overlapping and interleaving reads and writes) unless you introduce some form of MVCC (multi-version concurrency control) I've built tools to visualize how complex highly concurrent UIs work under the hood and found the principles and methods to be directly applicable to analysis of microservices based apps.
- nawgz 6y agoImmer seems like it lets you take the same approach as mobx, but instead of rerendering based on an optimized run-time constructed dependency graph, Immer has to rebuild every single item "under" your mutation. Doesn't this seem like it would be insanely expensive for modifying arrays or things like this? I also have to imagine the amount of boilerplate you write to use Redux + Immer is orders of magnitude over mobx, but maybe some people prefer it to be slightly more explicit
- acemarke 6y agoImmutable updates in JS have always required making copies of each level of nesting that has to be updated [0]. However, that process is very tedious and error-prone due to writing lots of nested spread operations. Immer effectively does those same steps, but automatically. This is all completely different than how Mobx works. Immer has a slight performance overhead [1], but in practice reducer logic is almost never a meaningful perf bottleneck in a React+Redux app - the cost of updating the UI is might higher. It's also worth noting that Immer was actually created by Michel Weststrate, the author of Mobx :) [0] https://redux-toolkit.js.org/usage/immer-reducers#basics-of-immutability https://redux-toolkit.js.org/usage/immer-reducers#basics-of-... [1] https://immerjs.github.io/immer/docs/performance https://immerjs.github.io/immer/docs/performance
- nawgz 6y agoYes, absolutely that is my understanding of immutability. It's why I asked the performance question, but Immer docs are convincing, I see your point. Not a surprise to me that mwestrate is the author after seeing the description of Immer - he has an excellent graph knowledge and applies clever architectures & optimizations from that. I recognize it's completely different from how MobX works, I simply mean to say that I feel MobX is superior and this mere idea of mutability / copying instead of smartly updating a graph and correspondingly only the observer portions of your UI seems like the core of that
- hesarenu 6y agoI have replaced redux with just react-query and hook,context. Simple for noobs as well.