npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

rekv

v1.2.2

Published

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

Downloads

152

Readme

Rekv

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

English Document

Travis CI Coveralls NPM version Downloads

特色

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

目录

Demo

  • 预览地址: https://csb-s8sbu.netlify.app/
  • 在线编辑: https://codesandbox.io/s/strange-antonelli-s8sbu

安装方式

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