DEV Community

loading...
Cover image for Why we wrote (yet) another state management tool

Why we wrote (yet) another state management tool

adam klein
I'm a web developer and consultant, web GDE, and author of open source libraries. I co-founded 500Tech, a company that specializes in frontend technologies. I love coding, and love speaking about code
・2 min read

Redux vs. MobX?

Most current state management solutions don't let you manage state using hooks, which causes you to manage local and global state differently and have a costly transition between the two.

Which brought us to look for solutions that use React hooks. The problem is that hooks only run inside React components.

What about Context?!

Using plain React Context is not the best solution for state management:

  • When managing global state using Context in a large app, you will probably have many small, single-purpose providers. Soon enough you'll find a Provider wrapper hell.
  • When you order the providers vertically, you can’t dynamically choose to depend on each other without changing the order, which might break things.
  • Context doesn't support selectors, render bailout, or debouncing

Our guidelines

To have global state management, we need a top-level provider. We wanted the developer to manage immutable state using hooks. We also wanted to allow for selectors and render-bailout for performance reasons. And lastly, we wanted to make sure there is no initialization code so that packages that use state management are easily pluggable into your app.

Iterating over and over the API got us to a solution that we feel is easy and powerful. We called the library Reusable. Here is the API:

Provider:

const App = () => (
  <ReusableProvider>
    ...
  </ReusableProvider>
)

Define a store:

const useCounter = createStore(() => {
  const [counter, setCounter] = useState(0);

  return {
    counter,
    increment: () => setCounter(prev => prev + 1)
  }
});

Subscribe to the store:

const Comp1 = () => {
  const something = useCounter();
}

const Comp2 = () => {
  const something = useCounter(); // same something
}

Use a selector:

const Comp1 = () => {
  const isPositive = useCounter(state => state.counter > 0);
   // Will only re-render if switching between positive and negative
}

Find out more

To find out more and start experimenting with Reusable, visit the repo:

https://github.com/reusablejs/reusable

You can also check out the video from ReactNext, where Maayan Glikser and myself present the library:

Discussion (0)