@liyuanqiu/react-final-state
TypeScript icon, indicating that this package has built-in type declarations

1.0.3 • Public • Published

Build Status codecov.io Known Vulnerabilities minified + gzip styled with prettier

react-final-state

final-state for React

Installation

yarn add final-state
yarn add react-final-state

You should care about the peer dependencies of these two packages. If something not installed, just install them manually.

final-state and react-final-state are written in Typescript, so you don't need to find a type definition for it.

Quick Start

Prepare store instance

You can instantiate the store instance anywhere and export it out for use.

// file: YOUR_PATH/store.js
import { createStore } from 'final-state';

// 1. define the whole state tree
const initialState = {};
// 2. define actions
const actions = {
  fooAction(draftState) {
    // ...
  },
  barAction(draftState, params) {
    // ...
  },
};
// 3. create store instance and export it out
export default createStore(initialState, actions, 'store-name-1');

You may want to use multiple store in your app, that's fine, just create multiple store instances and export them out:

// file: YOUR_PATH/store.js
import { createStore } from 'final-state';

const fooInitialState = {};
const fooActions = {
  fooAction(draftState) {
    // ...
  },
},
export const fooStore = createStore(fooInitialState, fooActions, 'foo');

const barInitialState = {};
const barActions = {
  barAction(draftState) {
    // ...
  },
},
export const barStore = createStore(barInitialState, barActions, 'bar');

How to track state

Just one line!!!

import { useCriteria } from 'react-final-state';
import store from '<YOUR_PATH>/store';

/* Assume your state object is like this:
{
  cpu: {
    load: {
      m1: 2.5,
      m5: 1.2,
      m15: 1.03,
    },
  },
}
*/

export default function MyComponent() {
  // `store` is the store instance
  // `'cpu.load.m5'` is the path of state you want to track in the whole state object
  const load5 = useCriteria(store, 'cpu.load.m5');
  return <h1>{load5}</h1>;
}

How to alter state

import { store } from '<YOUR_PATH>/store';

// React component
function MyComponent() {
  useEffect(() => {
    // Dispatch action to alter state
    // This is a side effect!
    // DO NOT write it directly in a function component
    store.dispatch('YourActionType');
  }, []);
  return *JSX*;
}

More details about dispatch and action, please see Store#dispatch.

API Reference

useCriteria

Important Note:

If you use useCriteria, your state must be a plain object. Continue reading for more details.

import { useCriteria } from 'react-final-state';

useCriteria is a react hook that helps you to get a deep branch's value from the state object.

// Example
const load5 = useCriteria(store, 'cpu.load.m5');

The signatures of useCriteria:

// `useCriteria` has 3 overloads
// store is the instance of Store
// path is the object path of your state
// setter is optional, set to true to get a setter of your state
function useCriteria<T>(store: Store, path: string): T | undefined;

function useCriteria<T>(
  store: Store,
  path: string,
  setter: false,
): T | undefined;

function useCriteria<T>(
  store: Store,
  path: string,
  setter: true,
): [T | undefined, (value: T) => void];

It's inner implementation is:

lodash.get(store.getState(), path);

So the path can be:

path = 'a[0].b.c';
path = 'a.b.c';
path = 'a[0][1][2].b.c';

See https://lodash.com/docs/4.17.11#get for more details about path.

If your path is invalid or not existing, you'll get a undefined from useCriteria.

If you set setter parameter to true, the return type of useCriteria will be an array of 2 elements:

  • #0 the state you are tracking
  • #1 the setter function of the state you are tracking

(Just think about const [count, setCount] = useState())

useSubscription

import { useSubscription } from 'react-final-state';

useSubscription is a react hook that helps you to subscribe the changes of state and automatically manages the lifecycle of a subscription.

Usually you can use useCriteria instead, only for those special cases you can give useSubscription a try.

// Example
const listener = React.useCallback(...);
// store is the instance of Store
useSubscription(store, listener);

Test

This project uses jest to perform testing.

yarn test

Road Map

  • [x] Fix tests

  • [x] Codecov 100%

Readme

Keywords

none

Package Sidebar

Install

npm i @liyuanqiu/react-final-state

Weekly Downloads

1

Version

1.0.3

License

MIT

Unpacked Size

25 kB

Total Files

13

Last publish

Collaborators

  • liyuanqiu