capitalsix-react-global-state
v0.1.0
Published
A lightweight TypeScript-first factory for shared global React state with optional sync/async loaders.
Downloads
156
Readme
capitalsix-react-global-state
capitalsix-react-global-state is a lightweight React utility for creating strongly typed shared state hooks.
It is designed for small and medium applications that want:
- Shared state across multiple components without adding a large state library.
- A typed API with predictable behavior.
- Optional sync or async bootstrapping via loader functions.
- A simple publishable package shape for reuse across projects.
Features
- TypeScript-first API.
- Shared state synchronized across all hook consumers created by the same factory.
- Supports direct value updates and functional updates (
prev => next). - Optional loader support with built-in loading state.
- Works with synchronous and asynchronous loaders.
Installation
npm install capitalsix-react-global-statePeer dependencies:
reactreact-dom
Quick Start
import { createGlobalState } from 'capitalsix-react-global-state';
type CounterState = {
count: number;
};
const useCounterState = createGlobalState<CounterState>({ count: 0 });
export function CounterA() {
const { state, setState } = useCounterState();
return (
<button onClick={() => setState((prev) => ({ count: prev.count + 1 }))}>
A: {state.count}
</button>
);
}
export function CounterB() {
const { state } = useCounterState();
return <p>B sees: {state.count}</p>;
}Both components read/write the same shared state because they use the same factory instance.
API
createGlobalState(initialState, stateLoader?)
Creates and returns a custom hook.
Parameters:
initialState: T- Initial shared state.stateLoader?: () => T | Promise<T>- Optional loader that runs once per factory lifecycle.
Returns a hook with:
state: TsetState: (next: T | (prev: T) => T) => voidloading: booleanperformLoad: (loader: () => T | Promise<T>) => void
Examples
1) Functional updates
import { createGlobalState } from 'capitalsix-react-global-state';
const useTodoCount = createGlobalState({ total: 0 });
function AddTodoButton() {
const { setState } = useTodoCount();
return (
<button
onClick={() => {
setState((prev) => ({ total: prev.total + 1 }));
}}
>
Add todo
</button>
);
}2) Load initial state asynchronously
import { createGlobalState } from 'capitalsix-react-global-state';
type SessionState = {
userId: string | null;
token: string | null;
};
const useSession = createGlobalState<SessionState>(
{ userId: null, token: null },
async () => {
const response = await fetch('/api/session');
const data = await response.json();
return { userId: data.userId, token: data.token };
},
);
function SessionGate() {
const { state, loading } = useSession();
if (loading) return <p>Loading session...</p>;
if (!state.userId) return <p>Not signed in</p>;
return <p>Signed in as {state.userId}</p>;
}3) Trigger manual reloads
import { createGlobalState } from 'react-global-state';
const useProfile = createGlobalState({ name: 'Unknown' });
function ReloadProfileButton() {
const { performLoad, loading } = useProfile();
return (
<button
disabled={loading}
onClick={() => performLoad(async () => {
const response = await fetch('/api/profile');
return response.json();
})}
>
{loading ? 'Reloading...' : 'Reload profile'}
</button>
);
}