🔄 Global State in React Without Context API or External Libraries

Anmol KansalAnmol Kansal
2 min read

Managing the global state is a common challenge in React. While tools like Redux, Zustand, or even React’s built-in Context API are popular choices, they can sometimes feel like overkill for simpler use cases.

What if you could share the state between components without any of that?

Let’s build a custom hook that does just that — global state without context, in under 30 lines of code.

✅ When Would You Use This?

  • You need a shared state across a few components

  • You want to avoid boilerplate

  • You don't need advanced features like middleware or persistence

🧠 useGlobalState Implementation

The idea is to make a simple shared store using closure and use subscription pattern -

// globalState.ts
import { useEffect, useState } from 'react';

type Subscriber<T> = (value: T) => void;

function createGlobalState<T>(initialValue: T) {
  let state = initialValue;
  const subscribers = new Set<Subscriber<T>>();

  const setState = (newValue: T) => {
    state = newValue;
    subscribers.forEach((callback) => callback(state));
  };

  const useGlobalState = () => {
    const [localState, setLocalState] = useState(state);

    useEffect(() => {
      const callback = (newValue: T) => setLocalState(newValue);
      subscribers.add(callback);
      return () => subscribers.delete(callback);
    }, []);

    return [localState, setState] as const;
  };

  return useGlobalState;
}

🧪 Example Usage

We can call createGlobalState fn to get a global hook -

const useGlobalCounter = createGlobalState(0);

const ComponentA = () => {
  const [count, setCount] = useGlobalCounter();
  return <button onClick={() => setCount(count + 1)}>Increment A: {count}</button>;
};

const ComponentB = () => {
  const [count, setCount] = useGlobalCounter();
  return <button onClick={() => setCount(count + 1)}>Increment B: {count}</button>;
};

Use both components anywhere in your tree, and they’ll stay in sync without a context provider.

⚠️ Caveats

  • It won’t work well for deep React trees with frequent updates.

  • Use wisely — for complex apps, dedicated state libraries are still a better fit.

📌 Summary

This pattern offers a minimal, dependency-free way to manage shared states in React apps. Great for small to mid-sized apps or feature-level global states — no Context, no boilerplate.

Give it a try and see how far you can go without reaching for Redux or Context. 🚀

0
Subscribe to my newsletter

Read articles from Anmol Kansal directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Anmol Kansal
Anmol Kansal

Web Development allows me to bring my ideas to life. Passionate about Web Development and Proficient in Data Structures and Algorithms, I like to solve challenging problems.