npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

react-hooks-global-states

v15.0.8

Published

This is a package to easily handling global-state across your react-components using hooks.

Readme

react-hooks-global-states 🌟

Image John Avatar

Effortless global state management for React & React Native & Preact! 🚀 Define a global state in just one line of code and enjoy lightweight, flexible, and scalable state management. Try it now on CodePen and see it in action! ✨


🔗 Explore More


🚀 React Hooks Global States - DevTools Extension

React Hooks Global States includes a dedicated, devTools extension to streamline your development workflow! Easily visualize, inspect, debug, and modify your application's global state in real-time right within your browser.

🔗 Install the DevTools Extension for Chrome

📸 DevTools Highlights

| Track State Changes | Modify the State | | ------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | | Track State Changes | Modify the State | | Effortlessly monitor state updates and history. | Instantly edit global states directly from the extension. |


| Restore the State | Custom Actions Granularity | | --------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | | Restore the State | Custom Actions Granularity | | Quickly revert your application to a previous state. | Precisely debug specific actions affecting state changes. |

🛠 Creating a Global State

Define a global state in one line:

import createGlobalState from 'react-hooks-global-states/createGlobalState';
export const useCount = createGlobalState(0);

Now, use it inside a component:

const [count, setCount] = useCount();
return <Button onClick={() => setCount((count) => count + 1)}>{count}</Button>;

Works just like useState, but the state is shared globally! 🎉


🎯 Selectors: Subscribing to Specific State Changes

For complex state objects, you can subscribe to specific properties instead of the entire state:

export const useContacts = createGlobalState({ entities: [], selected: new Set<number>() });

To access only the entities property:

const [contacts] = useContacts((state) => state.entities);
return (
  <ul>
    {contacts.map((contact) => (
      <li key={contact.id}>{contact.name}</li>
    ))}
  </ul>
);

📌 Using Dependencies in Selectors

You can also add dependencies to a selector. This is useful when you want to derive state based on another piece of state (e.g., a filtered list). For example, if you're filtering contacts based on a filter value:

const [contacts] = useContacts(
  (state) => state.entities.filter((item) => item.name.includes(filter)),
  [filter],
);

Alternatively, you can pass dependencies inside an options object:

const [contacts] = useContacts((state) => state.entities.filter((item) => item.name.includes(filter)), {
  dependencies: [filter],
  isEqualRoot: (a, b) => a.entities === b.entities,
});

Unlike Redux, where only root state changes trigger re-selection, this approach ensures that derived values recompute when dependencies change while maintaining performance.


🔄 Reusing Selectors

📌 Creating a Selector

export const useContactsArray = useContacts.createSelectorHook((state) => state.entities);
export const useContactsCount = useContactsArray.createSelectorHook((entities) => entities.length);

📌 Using Selectors in Components

const [contacts] = useContactsArray();
const [count] = useContactsCount();

✅ Selectors support inline selectors and dependencies

You can still use dependencies inside a selector hook:

const [filteredContacts] = useContactsArray(
  (contacts) => contacts.filter((c) => c.name.includes(filter)),
  [filter],
);

✅ Selector hooks share the same state mutator

The state api is stable across renders meaning actions and setState functions stay consistent.

const [, setState1] = useContactsArray();
const [contacts] = useContactsCount();

console.log(setState1 === useContacts.setState); // true

🎛 State Actions: Controlling State Modifications

Restrict state modifications by defining custom actions:

export const useContacts = createGlobalState(
  { filter: '', items: [] },
  {
    actions: {
      async fetch() {
        return async ({ setState }) => {
          const items = await fetchItems();
          setState({ items });
        };
      },
      setFilter(filter: string) {
        return ({ setState }) => {
          setState((state) => ({ ...state, filter }));
        };
      },
    },
  },
);

Now, instead of setState, the hook returns actions:

const [filter, { setFilter }] = useContacts();

🌍 Accessing Global State Outside Components

You can access and manipulate global without hooks, useful for non-component code like services or utilities. Or for non reactive components.

console.log(useContacts.getState()); // Retrieves the current state

✅ Subscribe to changes

const unsubscribe = useContacts.subscribe((state) => {
  console.log('State updated:', state);
});

✅ Subscriptions are great when one state depends on another.

const useSelectedContact = createGlobalState(null, {
  callbacks: {
    onInit: ({ setState, getState }) => {
      useContacts.subscribe(
        (state) => state.contacts,
        (contacts) => {
          if (!contacts.has(getState())) setState(null);
        },
      );
    },
  },
});

🎭 Using Context for Scoped State

  • Scoped State – Context state is isolated inside the provider.
  • Same API – Context supports selectors, actions, and state controls.

📌 Creating a Context

import createContext from 'react-global-state-hooks/createContext';

export const counter = createContext(0);

export const App = () => {
  return (
    <counter.Provider>
      <MyComponent />
    </counter.Provider>
  );
};

export const Component = () => {
  const [count, setCount] = counter.use();

  return <Button onClick={() => setCount((c) => c + 1)}>{count}</Button>;
};

export const Component2 = () => {
  const [count, setCount] = counter.use.api(); // non reactive access to the context api

  return <Button onClick={() => setCount((c) => c + 1)}>{count}</Button>;
};

Wrap your app:

<CounterProvider>
  <MyComponent />
</CounterProvider>

Use the context state:

const [count] = useCounterContext();

📌 Context Selectors

Works just like global state, but within the provider.


🔥 Observables: Watching State Changes

Observables let you react to state changes via subscriptions.

📌 Creating an Observable

export const useCounter = createGlobalState(0);
export const counterLogs = useCounter.createObservable((count) => `Counter is at ${count}`);

📌 Subscribing to an Observable

const unsubscribe = counterLogs((message) => {
  console.log(message);
});

📌 Using Observables Inside Context

useEffect(() => {
  const unsubscribe = useCounterContext.subscribe((count) => {
    console.log(`Updated count: ${count}`);
  });

  return unsubscribe;
}, []);

⚖️ createGlobalState vs. createContext

| Feature | createGlobalState | createContext | | ---------------------- | ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------ | | Scope | Available globally across the entire app | Scoped to the Provider where it’s used | | How to Use | const useCount = createGlobalState(0) | const counter = createContext(0); counter.Provider, counter.use() | | createSelectorHook | useCount.createSelectorHook | counter.use.createSelectorHook() | | inline selectors? | ✅ Supported | ✅ Supported | | Custom Actions | ✅ Supported | ✅ Supported | | Observables | useCount.createObservable | counter.api().createObservable() | | Best For | Global app state (auth, settings, cache) | Scoped module state, reusable component state, or state shared between child components without being fully global |

🔄 Lifecycle Methods

Global state hooks support lifecycle callbacks for additional control.

const useData = createGlobalState(
  { value: 1 },
  {
    callbacks: {
      onInit: ({ setState }) => {
        console.log('Store initialized');
      },
      onStateChanged: ({ state, previousState }) => {
        console.log('State changed:', previousState, '→', state);
      },
      computePreventStateChange: ({ state, previousState }) => {
        return state.value === previousState.value;
      },
    },
  },
);

Use onInit for setup, onStateChanged to listen to updates, and computePreventStateChange to prevent unnecessary updates.

Metadata

There is a possibility to add non reactive information in the global state:

const useCount = createGlobalState(0, { metadata: { renders: 0 } });

How to use it?

const [count, , metadata] = useCount();

metadata.renders += 1;

🎯 Ready to Try It?

📦 NPM Package: react-hooks-global-states

🚀 Simplify your global state management in React & React Native today! 🚀