Now with Partition Management

    rekv
    TypeScript icon, indicating that this package has built-in type declarations

    1.2.2 • Public • Published

    Rekv

    Rekv 是一个为 React 函数式组件设计的全局状态管理器,且对类组件具有很好的兼容,所有方法与状态均有 TypeScript 提示

    English Document

    Travis CI Coveralls NPM version Downloads

    特色

    • 一个简单但易用的状态管理器
    • 高性能,使用 Key-Value 而不是树型结构来处理状态
    • 支持 TypeScript 静态检查
    • 支持状态变更事件委托(拦截器)
    • 无 Redux,无依赖,仅 state
    • 不使用高阶组件(HOC)

    目录

    Demo

    安装方式

    yarn add rekv

    版本要求:React 版本 >= 16.8.0

    快速使用

    适用于小型项目,只需要一个全局状态

    // Demo.tsx
    import React from 'react';
    import { globalStore } from 'rekv';
     
    export default function Demo() {
      // 使用状态
      const { name } = globalStore.useState('name');
      return <div>Hello, {name}</div>;
    }
     
    // 在另一个文件,或其他地方调用
    globalStore.setState({ name: 'Jack' });

    API

    • class Rekv

      • new Rekv(object)

        创建一个 Rekv 的实例

      • delegate 全局事件委托

        全局事件委托,可设置所有 Rekv 实例的事件委托

        • beforeUpdate 状态更新前的事件,可对设置的状态进行拦截,检查并修改

          import Rekv from 'rekv';
           
          // 所有 `Rekv` 的实例,在更新前都将执行此方法
          // state: 使用 setState() 更新的状态值
          // store: 需要更新状态的 store
          // 返回值: 如果需要拦截并修改 setState 的值,可返回一个新的对象,替换 setState 的值
          Rekv.delegate.beforeUpdate = ({ state, store }) => {
            console.log(store.currentState, state);
            // return state; // 可选,如果返回了新的值,则可实现对状态的拦截修改
          };
        • afterUpdate 状态更新后的事件,返回已更新的状态

          import Rekv from 'rekv';
           
          // 所有的 `Rekv` 实例,在完成状态更新后,执行此方法
          // state: 已更新的状态(这里已过滤掉未发生改变的状态)
          // store: 已更新状态的 store
          Rekv.delegate.afterUpdate = ({ state, store }) => {
            console.log(store.currentState, state);
          };
    • globalStore

      globalStore 是一个默认创建的 Rekv 类的实例,可使用 Rekv 实例的所有方法与属性

    • Rekv 实例属性与方法

      • .delegate 使用方式与 全局事件委托 相同

        实例的事件委托,如果和全局的事件委托同时设置了,会优先执行实例的事件委托,再执行全局的事件委托,使用方式用全局事件委托相同

      • .currentState 获取当前时刻实例的状态

      • .getCurrentState().currentState 功能相同

      • .useState()

        在函数式组件中订阅并使用状态,通过设置多个参数,可在一行使用多个状态

        import React from 'react';
        import store from './store';
         
        function Demo() {
          const s = store.useState('foo', 'bar');
         
          return (
            <div>
              {s.foo}{s.bar}
            </div>
          );
        }
      • .setState() 对状态进行更新

        import store from './store';
        // 方法1: 直接设置状态
        store.setState({ count: 1 });
        // 方法2: 使用一个回调函数,获取当前状态,并返回新的状态
        // state: 当前状态
        store.setState((state) => {
          return {
            count: state.count + 1,
          };
        });
      • .classUseState() 在类组件中使用状态

    高级用法

    适用于多个 Store 的情况,可对每个状态进行 TypeScript 静态检查

    函数式组件使用方式

    使用 Rekv 创建一个 store

    // store.ts
    import Rekv from 'rekv';
     
    export default new Rekv({
      name: 'test',
      count: 0,
    });

    使用状态

    import React from 'react';
    import store from './store';
     
    export default function Demo() {
      const { name, count } = store.useState('name', 'count');
     
      return (
        <div>
          {name}{count}
        </div>
      );
    }

    在另一个组件内更新状态

    import React from 'react';
    import store from './store';
     
    // 重置计数器
    function reset() {
      store.setState({ count: 0 });
    }
     
    function increment() {
      store.setState((state) => ({ count: state.count + 1 }));
    }
     
    function decrement() {
      store.setState((state) => ({ count: state.count - 1 }));
    }
     
    export default function Buttons() {
      return (
        <div>
          <button onClick={reset}>reset</button>
          <button onClick={increment}>+1</button>
          <button onClick={decrement}>-1</button>
        </div>
      );
    }

    在类组件中使用

    import React, { Component } from 'react';
    import store from './store';
     
    export default class MyComponent extends Component {
      s = store.classUseState(this, 'count');
     
      render() {
        return <div>{this.s.count}</div>;
      }
    }

    使用 TypeScript 类型检查

    // store.ts
    import Rekv from 'rekv';
     
    interface InitState {
      name: string;
      age?: number;
    }
     
    const initState: InitState = {
      name: 'Jack',
      age: 25,
    };
     
    const store = new Rekv(initState);
     
    export default store;
    // User.ts
    import React from 'react';
    import store from './store';
     
    export default function User() {
      // name 将被推断为 string 类型
      // age 将被推断为 number | undefined 类型
      const { name, age } = store.useState('name', 'age');
     
      return (
        <div>
          {name}{age}
        </div>
      );
    }

    获取当前时刻的状态

    import store from './store';
     
    // 获取当前时刻的状态
    store.currentState;
    // 或
    store.getCurrentState(); // 兼容旧版本的 API

    事件委托、拦截器

    import store from './store';
     
    store.delegate = {
      beforeUpdate: ({ state }) => {
        console.log('beforeUpdate', state);
        // 可在这里拦截 setState 的值,并进行修改
        return state;
      },
      afterUpdate: ({ state }) => {
        // afterUpdate 的 state 只包含了需要更新的状态
        console.log('afterUpdate', state);
      },
    };

    使用副作用

    import Rekv froom 'rekv';
     
    // 定义副使用
    const store = new Rekv(
      { foo: 'bar' },
      {
        effects: {
          changeFoo(name: string) {
            this.setState({ foo: name });
          },
        },
      }
    );
     
    // 使用副作用
    store.effects.changeFoo('hello')

    License

    MIT licensed

    Install

    npm i rekv

    DownloadsWeekly Downloads

    52

    Version

    1.2.2

    License

    MIT

    Unpacked Size

    24 kB

    Total Files

    10

    Last publish

    Collaborators

    • flare