Hacker News new | comments | ask | show | jobs | submit login
Ask HN: How do you manage state in your React application?
71 points by thamizhan2611 6 days ago | hide | past | web | favorite | 42 comments
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






Been using MobX for about three years and I think it is wonderful. Incredibly easy to use (mark your variable as observable, modify it like you would any normal variable, and any components which use those variables in their rendering and are marked as observers automatically update), very performant out of the box (only components affected by a change re-render so no shouldComponentUpdate needed) and some excellent features like computed variables for derived values which automatically update. I really urge everyone to try it out. There is the odd time when the abstraction us a bit leaky (e.g. working with arrays is a bit different to plain JS) but with proxies in MobX 5 this is much improved.

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.


There is a new alternative to MobX/MST - Reactronic:

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.


Try mobx-state-tree. It's basically MobX with Redux-like tree structure written by the guy who did MobX. It combines best of both worlds. We use it at work and it's just such pleasure to work with, highly recommend

It is indeen wonderfully easy to work with. However, it has some performance penalties. I found typescript in conjunction with pure MobX just as efficient.

Especially complex state de-/serialization is a breeze with serializr.


Yeah exactly, for my use case (mobile device, frequent state updates) I couldn’t justify the overhead of state-tree after doing some profiling. Shame as it looks great and would have been a good fit ofberwise.

Thanks for the pointer to serializr - I hadn’t seen that before!


I second this. I am surprised it is not more popular.

I have a few months of experience working with MobX and have read a lot of the community material. Since it's so flexible, there's a lot of different patterns you can do with MobX. I haven't been able to set on one, any suggestions?

The pattern I use is to create classes for stores, each store having a small, fairly well defined scope e.g. AuthenticationStore. These stores contain the observable variables, computed variables and action methods (I use strict mode) for working with the data. I allow the action methods to do other stuff like make HTTP calls etc too, I find life much easier that way rather than all the side-effects middleware hassle with Redux :)

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.


We use Redux at work for larger projects, React setState/Context for smaller ones, and I'm personally a huge fan of mobx-state-tree which I think is the best solution, and can be plugged into Redux if needed.

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)


I hate redux-form so. much.

In the past I used Redux extensively - and I have only good things to say about Redux. I recently started using React Context and found I was much more productive, to the extent that I went back and ripped out Redux code. The new hooks thing with useContext makes using context even easier.

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.


At my current job we use Redux, though I wouldn't choose it myself (it had been adopted already when I joined). I think Redux is best suited to very large and complex applications, with very disciplined and skilled engineering teams, who talk to each other, refactor code, and have the time to think through things like the correct arrangement of application state, providing reusable selectors. Those teams, of course, would probably also do fine without Redux.

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


FWIW, we recently added a new "action stack trace" feature to the Redux DevTools Extension that helps show exactly where each action was dispatched from [0].

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...


I'm a Redux maintainer. I'd specifically encourage folks to take a look at our new Redux Starter Kit package [0]. It includes several utilities that add good opinionated defaults around the small Redux core to simplify common use cases, including store setup, defining reducers, immutable update logic, and even creating entire "slices" of state without writing any action creators or action types by hand.

Long-term, I want this to be the standard way that most people use Redux.

[0] https://redux-starter-kit.js.org


I created my own library for it.

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


Using redux v4 with react-redux v5 for a large and complicated project. Was looking into react-redux v6 but it looks like there may be a significant performance hit (https://github.com/reduxjs/react-redux/issues/1164) so will hold off on it now.

react-apollo is very interesting to me, but my understanding is that we'd need a graphql compatible backend, which we don't have


Hi, I'm a Redux maintainer.

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.


I'm not sure how you guys qualify "large" forms, but our application is pretty much all inputs (dynamically generated somewhere between 25 and ~300 visible on screen at one time)

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 :)


If you've got any public examples of apps that are showing perf issues (especially with React-Redux v6), please let me know. Ditto if you can come up with a smaller repo or CodeSandbox that demonstrates the issues.

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.


> Using redux v4 with react-redux v5 for a large and complicated project. Was looking into react-redux v6 but...

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...


I'm not sure why you feel this relates to Redux, tbh.

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...


Back when Redux was fairly new, we used a "mixin" architecture with a single component refreshing the entire global state of the application. Unfortunately, this has been a horrible decision and we're currently moving towards a Redux based solution. Nonetheless, the rendering is still impressive.

https://cellcollective.org


apollo has a local state link (https://www.apollographql.com/docs/react/essentials/local-st...) but I did not find it useful.

Redux is fine but I guess with the new hooks functionality one can combine usereducer and contexts to create a much simpler state manager.


Mobx is my go to. It's fast, and a much easier mental model to integrate. Just inject the store you want into your components

@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.


there are a lot of options out there and this thread kind of surprised me was expecting more interesting submissions. you might want to look at the original flux:

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.


Full disclosure, I’m the author of Breezy, https://github.com/jho406/Breezy. An opinionated state shape and PJAX library for Redux.

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.


Hooks + Context seems like a win, as does xstate https://github.com/davidkpiano/xstate

If you don't have to support IE11, there has been a very interesting trend of JS Proxy based state managers (immer, react-easy-state, overmind, etc.). It reduces the boilerplate compared to redux while giving basically the same architecture. I have been using my own implementation, because react-easy-state did not work well with styled components (https://github.com/UgnisSoftware/lape), while I was building https://github.com/UgnisSoftware/Ugnis if you want to see this approach in use.

The concept of having one store with associated actions is a great one, but Redux itself has an enormous amount of boilerplate having to do with the fact that you do all calls into your state functions as events which is completely unnecessary. Every project I’ve worked on using redux ends up having a ton of different abstractions just to reduce the redux event boilerplate overhead. I use unstated https://github.com/jamiebuilds/unstated , which gives you the beneficial central store structure without the silly event concept.

I prefer mobx to redux bc it's simpler.

I would like to thank each and everyone for their response. I will go through the suggestions and see how I can incorporate them in my app and post an update later :)

May I suggest giving Muster a look? (https://news.ycombinator.com/item?id=19134930)

Redux. I really like keeping my state flat as the app I mainly work on has a lot of pages which use the same data. Complex component props are derived in mapStateToProps. I find reselect complex and hard to use with typescript, so I simply use memoized functions with memoize-one.

For my thick client robot management applications: Redux and an Immutable.Record. A very flat state. The only nested elements are GeoJSON features. Been doing this successfully across half a dozen deployed applications. It's really simple.

Just to offer a different viewpoint, my app is rather lightweight in features and a rather hierarchical structure. So I have bern able to manage just fine with props and state. It rather feels quite clean that way

Pass the things returned from useReducer() hook (state object + dispatch function) down via context. Then useContext() in child components.

How can you implement that, the useReducer must be inside the hooks component, so how can I export the value returned from useReducer to pass it into createContext ?

Been using the new Context API which has been super easy and simple to use. Though our product is not a giant SPA.

Using Redux at work, looking forward to trying out the newly released React Hooks for less sophisticated needs

http://meiosis.js.org - this is the best way to manage state

react-easy-state for smaller projects, apollo for bigger ones.

Redux is the best!



Applications are open for YC Summer 2019

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact

Search: