DEV Community

Vo Thanh Dat
Vo Thanh Dat

Posted on

React State Management: It's Just a Hook

Managing global state in React has historically been... complicated.

Redux asks you to write reducers, actions, and selectors. Context requires manual Providers and careful optimization to avoid re-renders. Zustand and others simplify things, but still force you to learn a new API for defining your store.

What if your global state could just be... a hook?

Introducing React State Custom.

The "It's Just a Hook" Philosophy

The core idea is simple: If you know how to write a custom React hook, you already know how to write a global store.

There are no new concepts to learn. No set functions injected into callbacks. No proxies to configure. Just standard React hooks.

1. Write Your Logic (It's just a hook)

You start by writing a standard custom hook. Use useState, useEffect, useMemoโ€”whatever you need.

// hooks/useCounter.ts
import { useState } from 'react';

export const useCounterLogic = ({ initial = 0 }) => {
  const [count, setCount] = useState(initial);
  const increment = () => setCount(c => c + 1);

  return { count, increment };
};
Enter fullscreen mode Exit fullscreen mode

2. Make it Global (One line)

Wrap your hook with createStore. This returns a useStore hook that components can use to access the shared state.

// stores/counterStore.ts
import { createStore } from 'react-state-custom';
import { useCounterLogic } from '../hooks/useCounter';

export const { useStore } = createStore('counter', useCounterLogic);
Enter fullscreen mode Exit fullscreen mode

3. Use it Anywhere

Consume the state in any component.

// components/Counter.tsx
import { useStore } from '../stores/counterStore';

export function Counter() {
  // This component will ONLY re-render when 'count' changes
  const { count, increment } = useStore({ initial: 10 });

  return <button onClick={increment}>Count: {count}</button>;
}
Enter fullscreen mode Exit fullscreen mode

Wait, where's the <Provider>?

The Magic: AutoRootCtx

React State Custom eliminates the "Provider Hell" by using a single, smart component at the root of your app: <AutoRootCtx />.

// App.tsx
import { AutoRootCtx } from 'react-state-custom';

export default function App() {
  return (
    <>
      <AutoRootCtx /> {/* ๐Ÿ‘ˆ Handles all your stores automatically */}
      <YourAppContent />
    </>
  );
}
Enter fullscreen mode Exit fullscreen mode

This component acts as a dynamic host for all your active stores. When a component requests a store that doesn't exist, AutoRootCtx spins it up. When the last subscriber unmounts, it cleans it up.

Why You'll Love It

๐Ÿ’Ž Zero Boilerplate

Stop writing actions, types, and reducers. Just write hooks.

๐Ÿš€ Automatic Lifecycle Management

Stores are created on demand and destroyed when not in use. No more memory leaks from stale stores.

โšก Selective Re-renders

The useStore hook returns a proxy that tracks exactly which properties your component uses. If you only use increment, your component won't re-render when count changes.

๐Ÿ›ก๏ธ TypeScript Native

Because it's just a hook, TypeScript inference works perfectly out of the box. No complex type definitions required.

Get Started

Install it today and simplify your state management.

npm install react-state-custom
Enter fullscreen mode Exit fullscreen mode

Check out the Live Demo or read the full Documentation.

Top comments (0)