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>;

DevToolScreen

GitHub