Skip to content

πŸ“  React custom hook for persist state management (Web + React Native)

License

Notifications You must be signed in to change notification settings

marcel-happyfloat/little-state-machine

Β 
Β 

Repository files navigation

Little State Machine - React Hooks for state management

Little State Machine

State management made super simple

npm downloads npm npm

✨ Features

  • Tiny with 0 dependency and simple (less than 1.5kb)
  • Persist state by default (sessionStorage or localStorage)
  • 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',    
      // alternative you can just specify the store name and root state name { yourDetails: { firstName: '' } }
      // externalStoreName: ['yourDetail'],
      transform: ({ externalStoreData, currentStoreData }) => {
        return { ...externalStoreData, ...currentStoreData };
      },
    },
    // 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 { 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>
      <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>;

πŸ–₯ Browser Compatibility

Little State Machine supports all major browsers

For legacy IE11 support, you can import little-state-machine IE11 version.

import { createStore } from 'little-state-machine/dist/little-state-machine.ie11'

πŸ“‹ Polyfill

Consider adding Object.entries() polyfill if you're wondering to have support for old browsers. You can weather consider adding snippet below into your code, ideally before your App.js file:

utils.[js|ts]

if (!Object.entries) {
  Object.entries = function( obj ){
    var ownProps = Object.keys( obj ),
        i = ownProps.length,
        resArray = new Array(i); // preallocate the Array
    while (i--)
      resArray[i] = [ownProps[i], obj[ownProps[i]]];    
    return resArray;
  };
}

Or you can add core-js polyfill into your project and add core-js/es/object/entries in your polyfills.[js|ts] file.

About

πŸ“  React custom hook for persist state management (Web + React Native)

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • TypeScript 78.9%
  • JavaScript 21.1%