useStore
Simple, typesafe and easy to use global/local store for React. It has no dependencies besides React itself.
Counter
This counter is using useStore custom hook, to show and update its state
Installation
Copy whole useStore folder from repository. You can start using it right away, without any dependency.
Usage
Whole usage is based on two elements: StoreProvider and useStore hook. Store provider needs to wrap the component that will use the store, and useStore hook is used to access the store state and dispatch function.
import { StoreProvider, useStore } from "../hooks/useStore";
const NestedComponent = () => {
const { state, dispatch } = useStore();
const handleClick = () => {
dispatch({ type: "Set", payload: 10 });
};
return (
<div>
State: {state.counter}
<button onClick={handleClick}>
Set counter to 10!
</button>
</div>
);
};
const Example = () => {
return (
<StoreProvider>
<NestedComponent />
</StoreProvider>
);
};Configuration
storeState.tsx
This file is used to define the initial state of the store. It should contain the type of the store state and the initial value.
export type StoreStateType = {
counter: number;
};
export const initialStoreState: StoreStateType = {
counter: 0,
};reducer.tsx
This file is used to define the reducer function. It should contain the type of possible actions and the reducer function itself. Each action should have a unique type and a payload if needed. Make sure to spread the state object when returning a new state.
import { StoreStateType, initialStoreState } from "./storeState";
type PossibleActions = {
Increase: { type: "Increase" };
Decrease: { type: "Decrease" };
Set: { type: "Set"; payload: number };
Reset: { type: "Reset" };
};
export type ActionType = PossibleActions[keyof PossibleActions];
export const reducer = (state: StoreStateType, action: ActionType) => {
switch (action.type) {
case "Increase":
return { ...state, counter: state.counter + 1 };
case "Decrease":
return { ...state, counter: state.counter - 1 };
case "Set":
return { ...state, counter: action.payload };
case "Reset":
return initialStoreState;
default:
return state;
}
};API
There is only one parameter for StoreProvider component: initialState. It is optional and can be used to provide a custom initial state for the store.
<StoreProvider initialState={{ counter: 10 }}>
<NestedComponent />
</StoreProvider>