Install little-state-machine via npm
masterInstall the package using npm to add simple, zero-dependency state management to your project.
$ npm install little-state-machinerepository·master·Indexed 23 days ago
https://github.com/beekai-oss/little-state-machineA tiny, zero-dependency state management library for React 18+ designed for simplicity and performance. It features a global store initialized via createStore, built-in persistence (localStorage or sessionStorage), and optimized re-rendering using selectors via the useStateMachine hook. The library supports TypeScript type safety through the GlobalState interface and allows state interception via custom middleware.
Install the package using npm to add simple, zero-dependency state management to your project.
$ npm install little-state-machineIf upgrading from a previous version to V5, note the following breaking changes:
StateMachineProvider: The API is now simpler and does not require wrapping your app in a provider.useStateMachine({ actions: { updateName } }).To enable full type safety for your global state, declare the GlobalState interface within a global.d.ts file. This allows useStateMachine to automatically infer the types of state and actions.
import 'little-state-machine';
declare module 'little-state-machine' {
interface GlobalState {
yourDetail: {
name: string;
};
}
}The ActionsOutput type defines the shape of the functions returned by the state machine to trigger actions. Instead of returning the state directly, these functions accept an optional payload (matching the original callback's second argument) and an optional options object.
Passing { skipRender: true } in the options allows you to trigger an action without triggering a UI re-render.
export type ActionsOutput<
TCallback extends AnyCallback,
TActions extends AnyActions<TCallback>,
> = {
[K in keyof TActions]: (
payload?: Parameters<TActions[K]>[1],
options?: { skipRender: boolean },
) => void;
};When an action is called via the actions object returned by useStateMachine, the following lifecycle occurs:
middleWares are configured in createStore, they are executed in sequence. Each middleware receives the currentValue (the state resulting from the previous middleware or the action), the callback.name, and the payload. A middleware can return a new state or return undefined to keep the current state.storeFactory.state is updated with the final result.options.skipRender was not set to true in the action call, React is notified to re-render the component.options.persist is set to PERSIST_OPTION.ACTION, the store is automatically saved to storage.This example demonstrates initializing a store, defining an update action, using a selector for optimized rendering, and consuming state in components.
import { createStore, useStateMachine } from 'little-state-machine';
createStore({
yourDetail: { name: '' },
});
function updateName(state, payload) {
return {
...state,
yourDetail: {
...state.yourDetail,
...payload,
},
};
}
function selector(state) {
return state.yourDetails.name.length > 10;
}
function YourComponent() {
const { actions, state } = useStateMachine({ actions: { updateName } });
return (
<buttton onClick={() => actions.updateName({ name: 'bill' })}>
{state.yourDetail.name}
</buttton>
);
}
function YourComponentSelectorRender() {
const { state } = useStateMachine({ selector });
return <p>{state.yourDetail.name]</p>;
}
const App = () => (
<>
<YourComponent />
<YourComponentSelectorRender />
</>
);The useStateMachine hook provides access to the global state and the actions defined during store creation. It supports TypeScript generics for type safety.
Options:
actions (Record<string, Function>, optional): An object containing functions used to update the global state.selector (Function, optional): A function used to isolate re-renders. The component will only re-render when the value returned by the selector changes.Returns:
actions: The object of actions provided to the hook.state: The current global state.getState: A function to retrieve the current state directly.const { actions, state, getState } = useStateMachine<T>({
actions?: Record<string, Function> // Optional action to update global state
selector?: Function, // Optional selector to isolate re-render based on selected state
});Use createStore to initialize your application's global state. It accepts an initial state object and an optional configuration object.
Configuration Options:
name (string, optional): Rename the store.middleWares (array of functions, optional): Functions to invoke with each action.storageType (Storage, optional): Specifies the storage mechanism. Defaults to sessionStorage. Can be sessionStorage or localStorage.persist ('action' | 'beforeUnload' | 'none', optional):'none': State is not persisted.'action': State is saved to storage after a store action is completed (default).'beforeUnload': State is saved to storage before the page unloads.createStore(
{
yourDetail: { firstName: '', lastName: '' } // it's an object of your state
},
{
name?: string; // rename the store
middleWares?: [ log ]; // function to invoke each action
storageType?: Storage; // session/local storage (default to session)
persist?: 'action' // onAction is default if not provided
// when 'none' is used then state is not persisted
// when 'action' is used then state is saved to the storage after store action is completed
// when 'beforeUnload' is used then state is saved to storage before page unloa
},
);When initializing a state machine, you can provide a StateMachineOptions object to configure its behavior. Key options include:
name: A string identifier for the state machine.middleWares: An array of MiddleWare functions that intercept state changes.storageType: The storage mechanism used.persist: Configuration for state persistence (using PERSIST_OPTION).Use createStore to initialize the global state and configure the machine's options. It accepts a defaultState of type GlobalState and an optional StateMachineOptions object.
In non-production environments, createStore attaches debugging helpers to the window object:
window.__LSM_NAME__: The name of the store.window.__LSM_RESET__: A function to clear the store from storage (if a storageType is configured).Note that createStore configures the underlying storeFactory singleton, which manages the state across your application.
The useStateMachine hook is the primary way to consume the state machine within React components. It provides access to actions, the current state, and a synchronous way to retrieve the state.
actions: An object containing callback functions that define how the state should be updated. These are wrapped to automatically trigger re-renders and middleware.selector: An optional function (payload: TStore) => TStore used to select a specific slice of the state. The hook uses JSON.stringify comparison to determine if the selected slice has changed, triggering a re-render only when necessary.An object containing:
actions: The processed action callbacks.state: The current global state (triggers re-renders).getState: A function to retrieve the current state without subscribing to updates.createStore to initialize a new state machine store. This store manages the state transitions and holds the current state of your machine.