Stook: a minimalist react state management library

Time:2020-1-15

From hooks

A year ago, in September 2018, react hooks was just released. At that time, hooks was not stable API, and could only be used in version 16.7.0-alpha.0. At that time, I had a hunch that the state management solution based on hooks would gradually rise. At that time, I created an ideal state management library based on hooks: stamen.

I also wrote an article about it: probably the best state management tool based on hooks and typescript.

Review stamen

As I said before, I want a state management library like this:

  • Easy to use and suitable for medium and large projects
  • Perfect support for typescript

So I created stamen, which is more concise than Redux and has better support for typescript. More than a year has passed, and I have practiced in several small projects, and I found that I did not meet my two expectations very well.

Stamen’s API draws on the experience of DVA and rematch, which leads it not to be separated from the shadow of redux. It still has the concepts of state, reducers, effects, dispatch, selector, etc. it can be said that it is not completely hooking, especially the side effects of reducers’ processing synchronization and effects processing.

A year later, I created a more thorough Hooks state management Library: Stook.

About Stook

Stook, Chinese translation is gudui. The naming inspiration comes from the combination of store and hooks, a minimalist react state management library.

Basic Usage

Let’s see how simple the use of stook is. Here is a classic counter component, which showsstookBasic usage of:

import React from "react";
import { useStore } from "stook";

function Counter() {
  const [count, setCount] = useStore("Counter", 0);
  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>Click me</button>
    </div>
  );
}

Stook’s core API isuseStoreMaybe you found out that it’s related touseStateVery much like, in fact,useStoreIn addition to more than one parameter, the other usage is exactly the same.

The simplicity of stook is that its usage followsusStateAlmost the same, the learning cost can almost be ignored, and more learning cost lies in the mastery and understanding of react hooks. After more than one year, hooks has gradually been recognized in the react community. I believe that in the future, hooks will be the basic skills of every react developer.

State sharing

For state management, the core function is the cross component communication of state. Usestate is used to manage the state within a single component, and usestore can manage the state of the entire application across components.

The following shows how multiple components share state:

import React from "react";
import { useStore } from "stook";

function Counter() {
  const [count, setCount] = useStore("Counter", 0);
  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>Click me</button>
    </div>
  );
}

function Display() {
  const [count] = useStore("Counter");
  return <p>{count}</p>;
}

function App() {
  return (
    <div>
      <Counter />
      <Display />
    </div>
  );
}

In this example, we can see that to share the state, just use usestore to subscribe to the same key, which is very simple. It can be said that as long as you learn usestate, you will also learn usestore. As long as you learn usestore, you will learn the state management of react.

Customize hooks

In order to separate components from state management logic, it is strongly recommended to use custom hooks to manage state. For example, if you want to manage the state of counter, that is, to customize one calleduseCounterAnd then use theuseCounter(), not directlyuseStore('Counter')

Example:

import React from "react";
import { useStore } from "stook";

function useCounter() {
  const [count, setCount] = useStore("Counter", 0);
  const decrease = () => setCount(count - 1);
  const increase = () => setCount(count + 1);
  return { count, increase, decrease };
}

function Display() {
  const { count } = useCounter();
  return <div>{count}</div>;
}

function Increase() {
  const { increase } = useCounter();
  return <buttun onClick={increase}>+</buttun>;
}

function Decrease() {
  const { decrease } = useCounter();
  return <buttun onClick={decrease}>-</buttun>;
}

export default function App() {
  return (
    <div>
      <Decrease />
      <Display />
      <Increase />
    </div>
  );
}

The above three subcomponents use usecounter, which implements state sharing.

Customizing hooks is a best practice and it is highly recommended that you use them in your business.

Api

The core of stook is very simple. The core API isuseStoreOne, all APIs are three:

  • Usestore – View Details
  • Mute – View Details
  • Getstate – View Details

unit testing

It’s a very simple thing to test stoke, because to test stoke is to test react hooks.

It is recommended to use the react hooks testing library tool to test stoke.

Installation dependency

npm install -D @testing-library/react-hooks react-test-renderer

Example

useCounter.ts

function useCounter() {
  const [count, setCount] = useStore("Counter", 0);
  const decrease = () => setCount(count - 1);
  const increase = () => setCount(count + 1);
  return { count, increase, decrease };
}

useCounter.test.ts

import { renderHook, act } from "@testing-library/react-hooks";
import useCounter from "./useCounter";

test("should increment counter", () => {
  const { result } = renderHook(() => useCounter());

  act(() => {
    result.current.increase();
  });

  expect(result.current.count).toBe(1);
});

For more testing techniques, see: react hooks testing library.

debugging

Stook supports debugging with Redux devtools for better programming experience.

Install Redux devtools extension

If you do not have the Redux devtools extension installed, please install the plug-in of the corresponding browser: Redux devtools.

Setup

Using devtools is very simple. Install it firststook-devtoolsBag:

npm i stook-devtools

Then enter in the project code and initialize:

import { devtools } from "devtools";

devtools.init();

If you don’t want to introduce:

import { devtools } from "devtools";

if (process.env.NODE_ENV !== "production") {
  devtools.init();
}

Effect

After taking effect, you can see the state of the whole application in the Redux devtools extension of the browser:

Stook: a minimalist react state management library

summary

Stook’s concept is different from the traditional state management scheme, and there is no clear concept of action. As a matter of fact, its concept is similar to that of reactuseStateIt’s similar. It’s highly recommended: a hooks, a state and an action. Stook suggests splitting the states into hooks, and then[state, setState]

For more information on the use of stook, see GitHub: stook.

Recommended Today

Redis design and implementation 4: Dictionary Dict

In redis, the dictionary is the infrastructure. Redis database data, expiration time and hash type all take the dictionary as the underlying structure. Structure of dictionary Hashtable The implementation code of hash table is as follows:dict.h/dictht The dictionary of redis is implemented in the form of hash table. typedef struct dictht { //Hash table array, […]