React custom hook for persist state management
Little State Machine
State management made super simple.
✨ Features
- Tiny with 0 dependency and simple (less than 1.5kb)
- Persist state by default (
sessionStorage
) - Build with React Hooks
- Compatible with React Native
? Installation
$ npm install little-state-machine
? Demo
Check out the Demo.? API
? StateMachineProvider
This is a Provider Component to wrapper around your entire app in order to create context.
? createStore
createStore(store, options?: {
name: string; // rename the store
middleWares?: Function[]; // function to invoke each action
syncStores?: // sync with external store in your session/local storage
| Record<string, string[]>
| { externalStoreName: string; transform: Function } // name of the external store, and state to sync
| { externalStoreName: string; transform: Function }[];
}})
Function to initialize the global store, invoked at your app root (where <StateMachineProvider />
lives).
import yourDetail from './state/yourDetail';
function log(store) {
console.log(store);
}
createStore(
{
yourDetail, // it's an object of your state { firstName: '', lastName: '' }
},
{
middleWares: [log], // an array of middleWares, which gets run each actions
syncStores: {
// you can sync with external store and transform the data
externalStoreName: 'externalStoreName',
transform: ({ externalStoreData, currentStoreData }) => {
return { ...externalStoreData, ...currentStoreData };
},
},
// alternative you can just specify the store name and root state name { yourDetails: { firstName: '' } }
// syncStores : {
// externalStoreName: ['yourDetail'],
// }
// or you can pass in an array of transform function
// syncStores : [
// {
// externalStoreName: 'externalStoreName',
// transform: ({ externalStoreData, currentStoreData }) => {
// return { ...externalStoreData, ...currentStoreData };
// },
// }
// ]
},
);
? useStateMachine
This hook function will return action/actions and state of the app.
import { updateUserNameAction, removeNameAction } from './actions/yourDetails';
const { action, state } = useStateMachine(updateUserNameAction);
const { actions, state } = useStateMachine({
removeNameAction,
updateUserNameAction,
});
// The following examples are for optional argument
const { actions, state } = useStateMachine(
{
removeNameAction,
updateUserNameAction,
},
{
removeNameAction: 'removeName',
updateUserNameAction: 'updateUserName',
},
);
const { action, state } = useStateMachine(updateUserNameAction, {
shouldReRenderApp: false, // This will prevent App from re-render and only update the store
});
? Example
? app.js
import React from 'react';
import yourDetail from './yourDetail';
import YourComponent from './yourComponent';
import { StateMachineProvider, createStore } from 'little-state-machine';
import { DevTool } from 'little-state-machine-devtools';
// The following code is for React Native usage
// import { AsyncStorage } from "react-native";
// setStorageType(AsyncStorage);
// create your store
createStore({
yourDetail,
});
export default () => {
return (
<StateMachineProvider>
{process.env.NODE_ENV !== 'production' && <DevTool />}
<YourComponent />
</StateMachineProvider>
);
};
? yourComponent.js
import React from 'react';
import { updateName } from './action.js';
import { useStateMachine } from 'little-state-machine';
export default function YourComponent() {
const {
action,
state: {
yourDetail: { name },
},
} = useStateMachine(updateName);
return <div onClick={() => action({ name: 'bill' })}>{name}</div>;
}
? yourDetail.js
export default {
name: 'test',
};
? action.js
export function updateName(state, payload) {
return {
...state,
yourDetail: {
...state.yourDetail,
...payload,
},
};
}
⚒ Little State Machine DevTool
DevTool component to track your state change and action.
import { DevTool } from 'little-state-machine-devtools';
<StateMachineProvider>
<DevTool />
</StateMachineProvider>;