Ask HN: How do you manage state in your React application?
Is it recommended to use redux to share state across different components while you are using react-apollo client to sync remote data between client and server?
Looking forward to your views
Looking forward to your views
46 comments
[ 4.2 ms ] story [ 95.6 ms ] threadRedux is fine but I guess with the new hooks functionality one can combine usereducer and contexts to create a much simpler state manager.
I think Redux should not be used for everything (there are libraries like Redux-Form which I think are an anti-pattern as ephemeral state like that should never go through the root reducer on every key change)
Compared to redux it's far more simple and requires none of the boilerplate. It also allows perfect type support with typescript.
https://github.com/gunn/pure-store
Learning Redux, especially the "single source of truth" thing was very helpful, but my code is now simpler, easier to understand and faster to write.
I would recommend checking out React context and hooks. I would also recommend watching the Redux videos by Dan Abramov, even if you don't use Redux.
https://github.com/facebook/flux
from facebook if you app has a lot of global state needs multiple stores can be handy.
Mobx is great too:
https://github.com/mobxjs/mobx
With the current project I am working on we actually just vanilla javascript with singeltons with subscriptions (note: I did not write this, but I think it is rxjs).
anyways someone should come along with some answers.
Redux is still the easiest and with Sagas is really cool. One start up I interviewed with was using something similar to hooks, but do not remember the name of it.
Also datomic (used by om.next in clojurescript) has some really clever optimizations and is a joy to use.
I started out with Redux and I do think it’s worth learning - not just because it’s so widespread, but the concepts behind it are worth knowing and have influenced the way I design some stuff, but I found it really verbose and slow to work with compared to MobX (and more error prone) - there probably are libraries that help with this.
React Hooks look interesting for more simple use cases but I expect I’ll stick with MobX for the foreseeable future.
Especially complex state de-/serialization is a breeze with serializr.
Thanks for the pointer to serializr - I hadn’t seen that before!
I then use the “root store” pattern from the MobX docs (https://mobx.js.org/best/store.html) - I have a stores/index.ts file which contains a class containing instances of all the other top level stores. I can then instantiate the root store and access it either through Provider or as a singleton. Each store can have the instance of the root Store passed in to the constructor for cross-store communication, which can be convenient although I think other patterns such as callbacks are probably more architecturally sound.
https://github.com/Nezaboodka/reactronic#readme
It is transactionally reactive state management library for JavaScript. Key difference from MobX/MST is that Reactronic doesn't enforce developers to stick with MST rules of building the structure of state - the state can be a set (graph) of usual JS objects.
Also, Reactronic has minimal set of concepts, just three: State, Transaction, and Cache. So, it is easier to use.
Drawback is that it's a new thing and is not yet battle tested.
I think “how you shape your state to make it easy to reduce and share between components” is an important topic that’s taken a backseat when discussing state management tooling.
Should I repeat my backend models? Should I use a redux ORM? How much should I denormalize or normalize?
I found it much easier to just denormalize everything and shape state for presentational purposes, e.g, I have a bunch of page nodes in my redux state each with a duplicated header. If I need to make an update to the header in response to, say, a change in user email, I change each duplicated header individually.
Sounds insane but it really works for me and let’s me keep more business logic in the backend where it belongs.
https://cellcollective.org
react-apollo is very interesting to me, but my understanding is that we'd need a graphql compatible backend, which we don't have
This statement reminds me of my enterprise Java days. It consisted entirely of just gluing together an endless conglomeration of shit with Spring sitting at the center.
There was never actually any software development, just configuring an ever evolving mess of frameworks to talk to each other. When you offload all your engineering to frameworks, most of the bugs end up being due to some poorly understood interaction between components.
Kinda feels like the JavaScript world is starting to invent J2EE...
The Redux core is tiny and very stable. There were a couple technically "breaking" changes within the first couple months after it hit 1.0 in July 2015, and it stayed on 3.x until the middle of last year. The bump to 4.x was primarily due to updated TypeScript typings.
React-Redux has also been very stable, especially in terms of public API. We've reworked the internals a couple times to address various aspects of interacting with React, but the public API has been basically unchanged since the start of 2016.
I wrote a post on "The History and Implementation of React-Redux" that explains what React-Redux does, how it's evolved over time, and why the various changes were made:
https://blog.isquaredsoftware.com/2018/11/react-redux-histor...
I wouldn't call it a _significant_ performance hit. There's a measurable difference in our artificial stress tests benchmarks, and some users have reported slowdowns in specific scenarios (especially when large forms are connected to Redux).
I recently posted a roadmap issue with our plans for addressing the perf issues, and moving towards the ability to ship a hooks-based API for React-Redux:
https://github.com/reduxjs/react-redux/issues/1177
I've specifically spent the last week experimenting with reworking the internals of `connect` to come up with an alternative implementation that relies on direct store subscriptions again, and as of a couple days ago, I seem to have come up with something that is actually _faster_ than both v6 _and_ v5 in our benchmarks:
https://github.com/reduxjs/react-redux/issues/1177#issuecomm...
Still needs more investigating and testing, but this approach looks very promising.
We're also investigating hooks, we think we'd get some benefits from not having so many HOCs... specifically as our application is a _large_ form, unmounting components can sometimes be very expensive for us (common example: switching between two React tabs). Excited to see when you guys can release this change since it IS breaking, hopefully a major version change will suffice here :)
Our artificial stress test benchmarks are better than nothing, but I really want to get some more "real-world"-type scenarios put together that we can use to compare behavior.
@inject
and you can call/set @observables easily.
It's much easier to onboard people. Redux is just a spaghetti mess of files upon files, trying to find the actual implementation of something. A mess.
---
I also looked into Apollo and it's obscenely good! Terrific dev UX. I'm heavily researching it currently.
Long-term, I want this to be the standard way that most people use Redux.
[0] https://redux-starter-kit.js.org
If you have a team that writes spaghetti code, or never has time to refactor, or doesn't have effective communication then things will be worse with Redux, because it makes the code much harder to follow (good luck stepping through things in a debugger to see how they work, for example).
This is mostly intended as a criticism of people/teams who think adopting Redux will solve problems with the messiness of their code. But I also think Redux is overly complicated and too abstract for 95% of projects. And don't get me started on Sagas...
I would recommend setState as far as you can push it, then choosing something conceptually simple like MobX (Or MobX State Tree), React Easy State, or whatever the one from Formidable Labs is. Using Redux correctly is not as simple as it seems on the surface, and it requires real thought and real understanding o t
Also, I agree that sagas are not necessary for most apps, and we have some advice in the Redux FAQ on how to choose a side effects handling approach [1]. For most apps, thunks are more than sufficient.
[0] https://github.com/zalmoxisus/redux-devtools-extension/blob/...
[1] https://redux.js.org/faq/actions#what-async-middleware-shoul...