Creating a Context-less Data Store in React
Hello! It’s me again. This time I’m going to share a bit about my experimentation in creating a subscribe-based data store in React.
Now, you might have heard of redux before. Yes, it’s a framework-agnostic state management, although I think it was originally popular because of its usage with react, namely the react-redux package. You probably have also heard about nanostores, which can be integrated with other UI frameworks/libraries, e.g. with nanostores/react or nanostores/solid.
I happened to be curious about these store-based libraries, particularly for nanostores, because when we’re using React with Redux, we still need to have the store passed to the `Provider`
context component, whereas in nanostores, we just define the store and without requiring to define a Provider component, we can use the stores immediately.
According to the documentation of nanostores/react, this is the only thing that we need to do after defining the stores:
How cool is that? I think a lot of us (if not all) have seen this kind of code before if we’re using React.Context a bit out of control:
Now, borrowing the example code from nanostores with React above, we could do this instead with our DIY-store:
All that without React.Context! So, what’s the magic behind the `useStore`
? For this part, I have prepared a sandbox containing the demonstration. Now we’ll go through the code piece by piece.
First and foremost, nothing much. Just create a store with an ID, as well as the state and subscribers. The store content needs to be an object because if it’s not, then primitive types (such as string and number) would have been stored by value instead of reference. On top of that, we need to store the “subscribers” that we will “broadcast” whenever there is a new state coming in.
Next, we will define the `useStore`
hook.
We begin by creating a state with good-old `useState`
. After that, we set this `useEffect`
which would only be triggered once (in production). Here, we store the subscribers as well as remove the subscribers when the effect re-fires (in this case, probably only from the strict mode).
Of course, since this is a hook that can be reused in a lot of places, it’s best if we also memoize the `set`
function, so that we keep the referential equality intact. Finally, let’s use the store!
We first create the store by passing an object. After that, the returned store will be used as an argument to the `useStore`
function. There you have it, now when we increment in ComponentA, the count in ComponentB will also be increased, and vice versa. All without React.Context!
I hope you find this post useful. Take care and until next time!