The new wave of React state management

This page summarizes the projects mentioned and recommended in the original post on news.ycombinator.com

Our great sponsors
  • Appwrite - The Open Source Firebase alternative introduces iOS support
  • SonarLint - Clean code begins in your IDE with SonarLint
  • Scout APM - Less time debugging, more time building
  • TypeScript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

    I think it's because redux is quite painful to use with very modern apps. Most of the time you need something like `redux-saga` or `redux-thunk` to deal with async side effects. I'm not sure which is the most popular today, but sagas are based on generators and trying to use those with typescript is very very painful and the underlying issue [1] is marked as a design limitation in TS itself.

    https://github.com/microsoft/TypeScript/issues/32523

    In addition, if you want to have your app load as smaller chunks rather than a single large bundle, you need to be careful to ensure that things work even all the backing reducers aren't yet loaded.

  • vue-svelte-size-analysis

    Comparing generated code size of Vue and Svelte components

    The first version of React was released on 2013, it took almost 10 years for Suspense to exist (we _just_ got it now with React 18), that's what I'm talking about. Even functional components and hooks took a lot of time from them get and implement the idea after they tried to use ES classes and made everything much harder to manage. Context also isn't perfect, I like it but the redraw performance is not amazing and doesn't scale at all to bigger applications.

    > https://github.com/yyx990803/vue-svelte-size-analysis

    This is an interesting comparison I haven't seen before, I wonder if it's true for a complete application using some lib for state management, routing, etc. and if this isn't just a kind of cherry picked example. Thanks for showing this though.

  • Appwrite

    Appwrite - The Open Source Firebase alternative introduces iOS support . Appwrite is an open source backend server that helps you build native iOS applications much faster with realtime APIs for authentication, databases, files storage, cloud functions and much more!

  • devtools

    Replay.io DevTools (by replayio)

    Depends on what you mean here specifically :)

    I'll agree that the Redux DevTools "skip action" and "jump back to action" features are not all that commonly used in practice. I _maintain_ Redux, and I don't even use them that often.

    On the other hand, the ability to see a written list of all dispatched action type names is valuable by itself. So is the ability to click one of the listed actions and see the action contents, state diff, and final state. _That_ is very powerful.

    Beyond that... I now work at a company called Replay ( https://replay.io ), and we're building a true "time traveling debugger" for JS. Our app is meant to help simplify debugging scenarios by making it easy to record, reproduce and investigate your code.

    The basic idea of Replay: Use our special browser to make a recording of your app, load the recording in our debugger, and you can pause at any point in the recording. In fact, you can add print statements to any line of code, and it will show you what it would have printed every time that line of code ran!

    From there, you can jump to any of those print statement hits, and do typical step debugging and inspection of variables. So, it's the best of both worlds - you can use print statements and step debugging, together, at any point in time in the recording.

    I actually recently implemented a POC version of support for the Redux DevTools in our Replay debugging app, so that if you do record a Redux app (or Jotai, or Zustand, or NgRx), you can use that same Redux DevTools UI to see the action history.

    So, yes, time travel debugging _is_ an amazingly powerful concept. It's just ironic that that particular aspect of Redux didn't end up getting used that much... but the Redux DevTools themselves are still valuable, and Replay is actually a far superior "time travel debugger" overall.

  • pullstate

    Simple state stores using immer and React hooks - re-use parts of your state by pulling it anywhere you like!

    And automatically, any components using uiStateStore.useState and watching the isSidebarOpen property will get updated, exactly the same as the normal useState hook - just shared.

    It's so dead simple and has made complex app-building so much easier for me.

    The one caveat is that if I have a component with many handlers, e.g. onClick, onMouseMove, onContextMenu, onMouseLeave, etc (and in some cases I do), components can get bloated. I haven't found a fix to that yet. But that's more an inherent issue with react than anything to do with state management.

    [1] https://github.com/lostpebble/pullstate

  • inertia

    Inertia.js lets you quickly build modern single-page React, Vue and Svelte apps using classic server-side routing and controllers.

    Or you just manage state in the server. With https://inertiajs.com/ you can even afford to not to declare an API and still manage the state back there.

  • redux-toolkit

    The official, opinionated, batteries-included toolset for efficient Redux development

    Context and Redux are somewhat different tools and context doesn't necessarily solve the same problems as Redux. This article by the maintainer of Redux goes over why [0]. Have you tried Redux Toolkit as well? It cleans up a lot of the complexity of Redux and works well with TypeScript [1].

    [0] https://blog.isquaredsoftware.com/2021/01/context-redux-diff...

    [1] https://redux-toolkit.js.org/

  • joystick

    The full-stack JavaScript framework. Updates on Twitter: https://twitter.com/cheatcodetuts

    This is why I'm building Joystick: https://github.com/cheatcode/joystick.

    It riffs on the old, simple APIs of React but uses pure HTML, CSS, and JavaScript w/o any trickery (I'm also hardcore about not changing the component API so WYSIWYG).

    The bonus is that it's a part of a full-stack framework (the UI framework has a Node.js counterpart), so wiring up a full app is near-effortless.

  • SonarLint

    Clean code begins in your IDE with SonarLint. Up your coding game and discover issues early. SonarLint is a free plugin that helps you find & fix bugs and security issues from the moment you start writing code. Install from your favorite IDE marketplace today.

  • redux-eggs

    Add some Eggs to your Redux store.

    We have docs on code splitting reducers and other Redux logic here:

    - https://redux.js.org/usage/code-splitting

    There have been some different community packages for helping with that process, but some of them seem to have become outdated (only worked with React-Redux v5, etc). I did see a new one at https://github.com/fostyfost/redux-eggs that seemed like it had potential, but I haven't had a chance to try any of them myself.

    I also once saw someone play around with the idea of using React's still-not-technically-final Suspense support to help ensure that a lazy-loaded component that relies on a code-split reducer doesn't actually get rendered until that reducer's state is available. Don't have the link handy atm, but if someone wants it ping me and I can go figure out where that was described.

    Also, the new RTK "listener" middleware was specifically designed to replace almost all saga usages, and you can dynamically add more listeners at runtime via dispatch an `addListener()` action:

    - https://redux-toolkit.js.org/api/createListenerMiddleware

    - https://blog.isquaredsoftware.com/2022/05/presentations-evol...

  • redux-xstate-poc

    Manage your Redux side effects with XState. Use 100% of XState's features.

    Fun fact: one of the XState devs did a proof-of-concept showing how to use XState state machines as Redux reducers and integrate the side effects handling as a middleware:

    https://github.com/mattpocock/redux-xstate-poc

    We'd like to work together to turn that into a more official integration sometime soon.

  • grug-dev-translation

    The Grug Brained Developer - Plain English Translation

    Plain english translation: https://github.com/reidjs/grug-dev-translation

    I haven't read it, but wish I had seen it before struggling through the original

  • jotai

    👻 Primitive and flexible state management for React

    For anyone who has not had the pleasure of working with these simpler “atom-based” state management libraries, I would implore you to try Jotai (https://jotai.org/), which is mentioned in the article.

    Jotai’s atomic model and ease of use has completely changed the ease of writing complex React applications for me.

  • cra-template-redux-typescript

    The official Redux + TypeScript template for Create React App

    Yeah, _please_ don't use `typesafe-actions` :)

    It may have had some value before RTK came out, but a lot of the opinions and approaches shown in its docs lead you to write _wayyyy_ too much code. For example, we specifically recommend _against_ writing TS unions for action object types [0].

    RTK completely obsoletes `typesafe-actions`, and the TS usage patterns that we teach today should result in a pretty minimal set of types that you need to write in your own code.

    For a small example see the RTK+TS template for Create-React-App [1]. If you want to see what a real app codebase can look like, the client app for my day job at Replay.io is OSS [2]. It's admittedly a somewhat messy codebase due to its long evolution and legacy (started as the FF DevTools codebase, copy-pasted, and we've been slowly migrating to RTK+TS and modernizing it), but files like [3] show how I would write a real slice reducer with RTK+TS.

    [0] https://redux.js.org/usage/usage-with-typescript#avoid-actio...

    [1] https://github.com/reduxjs/cra-template-redux-typescript

    [2] https://github.com/replayio/devtools

    [3] https://github.com/replayio/devtools/blob/454804188d33900a26...

  • alt

    Isomorphic flux implementation

  • Next.js

    The React Framework

    I use Zustand with Next.js. What is the issue? There are even officially maintained examples by Next:

    https://github.com/vercel/next.js/tree/deprecated-main/examp...

  • redux-easy-mode

    Have you considered something like "selector based side effects"? https://github.com/mikew/redux-easy-mode#selector-based-side.... The difference is most side effects are based around when an action is dispatched, but I wanted to know when things _change_.

    It's possible to do the same thing with a react component + useEffect, but I thought a pure-redux solution would better fit the spirit of Redux.

  • Dn-FamiTracker

    modifications and improvements for 0CC-FamiTracker (based on j0CC-FamiTracker 0.6.3)

    Frankly I feel state management is a difficult task on desktop apps as well, to the point that tracking spaghetti-shaped causation and control flow is beyond my mental abilities. Qt itself as well as many apps are rife with redundantly calculating state or redrawing GUIs when changing the same value multiple times, or changing two values which both affect an outcome (my StateTransaction pattern mostly alleviates this issue with a set of dirty bitflags and recomputing all state dependent on those bits, though the reactivity system is currently hard-coded and statically dispatched, and generalizes poorly to open-ended state or managing the local state of many dialogs of the same type). And one of the craziest errors caused by witnessing malformed intermediate values is https://github.com/Dn-Programming-Core-Management/Dn-FamiTra..., where a sloppily-written "load document" function redrew the UI in the middle of mutating document state, causing the GUI to crash after observing a broken invariant.

    It saddens me that so much of research in developing better state management techniques is in such a bloated and dependency-laden environment as JavaScript on the web. I like QML's reactivity system, but its evaluation engine is JS-based, dynamically-typed, and dynamically-scoped, and the UI engine itself is a buggy mess. And GTK4's list APIs promise to be better than the clusterfuck of Qt Widgets/Quick's QAbstractItem{Model/View} system (which abstracts poorly over list/column/tree collections, and widget-internal, cross-widget, and cross-application drag-and-drop), but I haven't tried that either.

  • Frankly I feel state management is a difficult task on desktop apps as well, to the point that tracking spaghetti-shaped causation and control flow is beyond my mental abilities. Qt itself as well as many apps are rife with redundantly calculating state or redrawing GUIs when changing the same value multiple times, or changing two values which both affect an outcome (my StateTransaction pattern mostly alleviates this issue with a set of dirty bitflags and recomputing all state dependent on those bits, though the reactivity system is currently hard-coded and statically dispatched, and generalizes poorly to open-ended state or managing the local state of many dialogs of the same type). And one of the craziest errors caused by witnessing malformed intermediate values is https://github.com/Dn-Programming-Core-Management/Dn-FamiTra..., where a sloppily-written "load document" function redrew the UI in the middle of mutating document state, causing the GUI to crash after observing a broken invariant.

    It saddens me that so much of research in developing better state management techniques is in such a bloated and dependency-laden environment as JavaScript on the web. I like QML's reactivity system, but its evaluation engine is JS-based, dynamically-typed, and dynamically-scoped, and the UI engine itself is a buggy mess. And GTK4's list APIs promise to be better than the clusterfuck of Qt Widgets/Quick's QAbstractItem{Model/View} system (which abstracts poorly over list/column/tree collections, and widget-internal, cross-widget, and cross-application drag-and-drop), but I haven't tried that either.

  • vuex

    🗃️ Centralized State Management for Vue.js.

    > poor support for style libraries like tailwind

    Can't relate. Tailwind works fine with anything that supports PostCSS. I run it with Vite and there's zero issues.

    > the state management ecosystem is fractured between vuex and pinia

    This is also just not true. Pinia is officially replacing Vuex as the recommended store library for Vue [1]. They're also vastly similar in how they do things, so the knowledge transfer over from Vuex to Pinia. And Pinia just address most of the design goals mentioned in the article in the most simple way.

    As for Vue 2 -> 3 transition, lots of the larger UI frameworks in the ecosystem is struggling to migrate, despite lots of efforts on the compat layer to smooth the transition, which is a bummer. But as long as you're not doing those sophisticated things, Vue 2 examples should work out-of-box on Vue 3 as well. There are surely less resources for the composition API, but the official introduction guide has been good enough in my experience.

    [1]: https://vuex.vuejs.org/#what-is-vuex

  • primevue

    Next Generation Vue UI Component Library

    > As for Vue 2 -> 3 transition, lots of the larger UI frameworks in the ecosystem is struggling to migrate, despite lots of efforts on the compat layer to smooth the transition, which is a bummer.

    I actually recently looked into most of the frameworks out there and their migration efforts.

    So far, I only found three viable options for Vue 3:

      - PrimeVue https://www.primefaces.org/primevue/

NOTE: The number of mentions on this list indicates mentions on common posts plus user suggested alternatives. Hence, a higher number means a more popular project.

Suggest a related project

Related posts