Published at
Updated at
Reading time
1min

Yoav Kadosh shared a very useGlobalState React hook.

const store = {};
const listeners = {};

function useGlobalState(key, initialValue) {
  const [state, _setState] = useState(store[key] || initialValue);
  const setState = useCallback((stateOrSetter) => {
    let next = stateOrSetter;
    if (typeof stateOrSetter === "function") {
      next = stateOrSetter(store[key]);
    }

    listeners[key].forEach((l) => l(next));
    store[key] = next;
  }, []);
  useEffect(() => {
    // Store the initial state on the first call with this key
    if (!store[key]) {
      store[key] = initialValue;
    }
    // Create an empty array of listener on the first call with this key
    if (!listeners[key]) {
      listeners[key] = [];
    }
    // Register the observer
    const listener = (state) => _setState(state);
    listeners[key].push(listener);
    // Cleanup when unmounting
    return () => {
      const index = listeners[key].indexOf(listener);
      listeners[key].splice(index, 1);
    };
  }, []);
  return [state, setState];
}

You can then use the defined useGlobalState hook to share or update application state across components. 💪

const [state, setState] = useGlobalState('someUniqueKey', INITIAL_STATE);

Are there downsides to this pattern? I don't know, and I'm a little puzzled why I haven't seen this userland hook before, but if you think useGlobalState is a bad idea, let me know!

If you want to learn more, Yoav explains how it works on his blog!

If you enjoyed this article...

Join 5.5k readers and learn something new every week with Web Weekly.

Web Weekly — Your friendly Web Dev newsletter
Reply to this post and share your thoughts via good old email.
Stefan standing in the park in front of a green background

About Stefan Judis

Frontend nerd with over ten years of experience, freelance dev, "Today I Learned" blogger, conference speaker, and Open Source maintainer.

Related Topics

Related Articles