react-simple-hook-store
TypeScript icon, indicating that this package has built-in type declarations

0.0.6 • Public • Published

Simple React hook based state management

npm version

No Redux, no Mobx, no React Context API, just React hooks. React 16.8+ required.

The project is heavily based on the State Management with React Hooks — No Redux or Context API article and corresponding npm module. This project fixes some issues, adds tests, new features and written in TypeScript.

Table of contents

The idea

Your state is readonly and immutable. The only way to update the state from a component's code is through actions. If you want to update the state from outside a component, you can use store's setState method. All updates to the state should be immutable (the same way as you do it for React's setState in class based components). You should define the structure of your state, your actions and start using them in your components.

Installation

$ npm install react-simple-hook-store --save

Or just add dist/react-simple-hook-store.js in your project through the script reference.

Usage

Define your state structure:

interface IState {
    counter: number;
}

Define actions, which modify your state:

interface IActions {
    increment: () => void;
}

Create store. It accepts an initial state value as the first argument and your actions as the second.

import { createStore } from "react-simple-hook-store";

const { useStore, store } = createStore<IState, IActions>({
            counter: 0,
        }, {
          increment: (store) => {
                store.setState({
                    counter: store.state.counter + 1,
                });
            }
        });

createStore returns React hook called useStore, which you should use in your components. It accepts a map function, which returns subset of the whole state. The second param is actions map function. If you want all actions to be returned, omit this parameter.

const Component = () => {
    const [counter, increment] = useStore((s) => s.counter, (a) => a.increment);

    return (
        <button onClick={() => increment()}>
            {counter}
        </button>
    );
};

counter will be your "local state" here. Every time other components (or current component) update counter state variable, the component will get re-rendered. Another way to read it: any updates to counter global state will cause this component to be re-rendered.

If you want to modify the state outside of React component, you can use store exported on the previous step.

More examples

Basic usage

This sample contains bare minimum you need to setup to get started with react-simple-hook-store

Async actions

You can have async actions inside your store

Multiple stores

You can have as many stores as your application needs. There are two ways to handle it - either use "namespaces" or simply create separate stores (if your stores are completely unrelated)

Different ways to access your store from components

useStore hook has several overloads which might be useful in different situations.

Todo App

This sample showcases full Todo App. The store contains all todo items as an array and filter state. You don't necessarily need global state for your todos, but just for the demo purposes it's ok. It demonstrates how to update state correctly (immutably, including arrays).

API

createStore<IStore, IActions>(initialState, actions)

Creates a store.

Arguments

  • initialState: object, the initial state, supports multilevel, i.e.

    {
        appState: {
            value: "myvalue"
        },
        navigation: {
            active: "node1"
        }
    }
  • actions: StoreActions<IState, IActions> actions map. You use actions to modify state from components. For example:

      interface IState {
          counter: number;
      }
    
      interface IActions {
          increment: () => void;
      }
    
      const actions: StoreActions<IState, IActions> = {
          increment: store => {
                  store.setState({
                  counter: store.state.counter + 1
              });
          }
      }

Return value

Object with properties (more on every property below):

  • useStore - React hook to be used inside React functional components
  • store - store instance, might be useful outside of React components
  • batchUpdates - function wrapper to batch multiple setState to reduce the number of re-renders. For advanced performance tunning, in most cases you don't need it. More info below.

useStore(mapState, mapActions)

Arguments

  • mapState: a function, which returns a subset of the original state. When omitted, undefined will be returned. Current component will be re-rendered only if the result of mapState will be changed.
  • mapActions: a function, which returns a subset of actions. When omitted, all actions will be returned

Return value

An array with two values:

  • [0]: the result of mapState function, or undefined if mapState is undefined.
  • [1]: the result of mapActions function or all actions if mapActions is undefined

store object

Properties:

  • state - readonly state object
  • actions - all store actions

Methods:

  • setState - a function which accepts subset of original state to modify the state. Works the same way as React's setState in class based components, i.e. merges provided value with original state.

batchUpdates

A function, which accepts a callback. Inside that callback you can use as many store.setState as you wish. This will cause only one render inside React components.
When it might be useful? If you perform multiple state updates as a result of async function (or as a result of timeout function). By default React will re-render your component as a result of every call to setState. More info in this React issue.

Package Sidebar

Install

npm i react-simple-hook-store

Weekly Downloads

14

Version

0.0.6

License

MIT

Unpacked Size

30 kB

Total Files

12

Last publish

Collaborators

  • s-kainet