DEV Community

axtk
axtk

Posted on • Edited on

1

Straightforward shared state management in React: groundstate

Looking at the multitude of React state management libs like Redux, Zustand, Jotai, MobX, etc. (and using some of them), I was wondering: Can't we come up with something as straightforward and single-purpose as React's useState() for something as basic and nearly ubiquitous as shared state?

Most libs, while being working solutions, may seem a bit overloaded for the task of providing shared state. So I created another one to address my question.

It's called Groundstate, and that's how it works. We'll move a portion of a component's state to a shared location just by replacing useState() with another hook and by wrapping the state value with the Store class:

+ import {Store, useStore} from 'groundstate';

+ let AppContext = createContext(new Store(0));

let Counter = () => {
-   let [value, setValue] = useState(0);
+   let [value, setValue] = useStore(useContext(AppContext));

    let handleClick = useCallback(() => {
        setValue(value => value + 1);
    }, [setValue]);

    return <button onClick={handleClick}>{value}</button>;
};
Enter fullscreen mode Exit fullscreen mode

Before the changes, the counter value used to be visible only to the component itself. After the changes, the counter value can be accessed and changed from outside of the Counter component. In the example above, we've got a primitive value in the store, but it can be any type.

The point is this shared state setup introduces as few intermediaries as possible, and the interaction with the shared state remains the same as with local state from useState(). Which means the shared state setup is nearly effortless, also allowing for quick migration from local state to shared state and the other way around.

Optionally, besides sharing the state, moving the state out of the component in fact can also be used as persistent local state.

More details

As we saw in the example above, all what's needed to set up shared state is the useStore() hook and the Store class.

The Store class provides methods to access and update the state value. The useStore() hook subscribes the component to the store state changes and unpacks the state value from the store.

The reference to the instance of the Store class passed to the Context (initialized as new Store(0) in the example above) doesn't change when we update its state via setValue(): the store state changes, the store instance does not. Which means that updating the state doesn't trigger re-renders in the entire DOM tree nested into the Context Provider by default, affecting only the components that explicitly subscribed to the store via the useStore() hook. Besides, the useStore() hook also offers an option to fine-tune the component's responsiveness to store updates, when it's necessary.

And that's, in essence, what makes up the Groundstate's minimalist single-purpose approach to shared state management that I've been looking for.

View Groundstate on GitHub

Hot sauce if you're wrong - web dev trivia for staff engineers

Hot sauce if you're wrong · web dev trivia for staff engineers (Chris vs Jeremy, Leet Heat S1.E4)

  • Shipping Fast: Test your knowledge of deployment strategies and techniques
  • Authentication: Prove you know your OAuth from your JWT
  • CSS: Demonstrate your styling expertise under pressure
  • Acronyms: Decode the alphabet soup of web development
  • Accessibility: Show your commitment to building for everyone

Contestants must answer rapid-fire questions across the full stack of modern web development. Get it right, earn points. Get it wrong? The spice level goes up!

Watch Video 🌶️🔥

Top comments (0)

The best way to debug slow web pages cover image

The best way to debug slow web pages

Tools like Page Speed Insights and Google Lighthouse are great for providing advice for front end performance issues. But what these tools can’t do, is evaluate performance across your entire stack of distributed services and applications.

Watch video

👋 Kindness is contagious

DEV shines when you're signed in, unlocking a customized experience with features like dark mode!

Okay