How to make your own global state manager with only one hook

Pavel Dzhagriev
Webtips
Published in
3 min readAug 28, 2022

Imagine the task that you need to change the state of the same type of components affecting only one of them. Something very similar can be implemented using React context. But in this case we run the risk of getting re-render on all consumers of the context which isn’t very good idea if there are about 20,000 such consumers on the page at the same time.

In this note I’ll try to propose a solution that will allow you to change the state of only those consumers that need to be changed. Moreover, such behavior will be provided with just one hook. Actually, there will be nothing new here. We will simply take the publisher/subscriber pattern as a basis and teach it to work with states.

Let’s get to the code. First af all, let’s declare an object that will store the states of subscribers, divided by channel. As well as methods that allow you to work with subscribers.

We need channels to store the states of subscribers. Now implement subscribe method.

The idea is simple, we just put an object containing the state and a callback function that changes the state of the subscriber into the named pipe. Now, for cases when the subscription in no longer needed, implement the unsubscribe method.

Now we can save component states and eliminate state tracking. We just have to implement the methods that will change these states. I propose two such methods. One of them will change the states in the selected channel, and the other one will be exclusively for the subscriber which initiates the changes, Let’s start with the atomic change.

The method returns the state and a function to change it. This will help us in the future. In the meantime, let’s make a method for publishing a changes to subscribers in the selected channel.

Yes, very short but not all obvious. In fact, we do just that to provide the widest possible field of ability to manage states from anywhere. Further we’ll see how it works using an example component. For now, let’s take a look at the end result.

You can say: “It’s fine, but you promised us a hook!”. Well, the promise will not be long coming.

The hook expects to receive a channel name, an initial state, and a subscriber key as input. In this case, if the key is not set, it will be generated. The hook wil automatically unsubscribe the component if it is unmounted.

Let’s now see the hook in action with a simple example. We need to create an application component that displays four cards.

And the cards themselves, which will be subscribed to our new manager.

By clicking on the card, it will add a class. Let by this property it changes color for example. Note that when clicked, the state of all subscribers in the channel that met the condition will also change. In this example we will get only two re-renders.

What if we make the task more difficult and change the state of cards from another channel? Let’s add button that will clear the cards.

The App component has signed up to the root channel, but this does not prevent it from funding a card in cards channel and changing its state. In this case re-render will happen only for this card.

Thus, we got only one hook for storing component states with the ability to influence some states on others while maintaining relatively high performance.

Thanks for reading!

Example project: https://github.com/Pavloid21/state_hook_example

--

--