React通过useReducer实现局部状态模型管理代替redux全局数据管理

  1. 某些组件状态共享是存在范围的,并不需要扩大到全局,这时使用基于redux的soul状态模型就显得鸡肋了, 通过制作一个高阶组件让数据共享范围变小,同时让它使用体验与redux相同,这个实现多亏useReducer()的hooks函数。

  2. 先来看看使用方法

model高阶组件接收一个IModel的状态模型,这个状态模型与vuex和dvajs的思路是一致的。

IModel

  • state : 定义初始化状态
  • mutation : 定义同步派发函数,返回更新后的状态
  • immer : 与mutation函数相同,区别是无需返回更新状态,直接操作改写传入的state属性即可
  • action : 定义异步派发函数,函数必须使用async进行声明

dispatch()

  • actions : type属性名称需要和IModel中的mutation、immer或action 函数名保持一致才可正常派发到相应位置进行处理, payload用于传输额外参数
import React from "react";

import {useModel, model, delay} from "kiva";
import {useTab} from "@@/utils";

function Hello1() {
    const {state, dispatch} = useModel();
    return <div onClick={() => dispatch({type: "changeData", payload: "hello1"})}>hello1 {state.data}</div>;
}

function Hello2() {
    const {state, dispatch} = useModel();
    return <div onClick={() => dispatch({type: "asyncChangeData", payload: "async hello2"})}>hello1 {state.data}</div>;
}

function Hello3() {
    const {state, dispatch} = useModel();
    return <div onClick={() => dispatch({type: "changeData", payload: "hello3"})}>hello1 {state.data}</div>;
}

export default model({
    state: {
        data: ""
    },
    mutation: {
        changeData(state, action) {
            return {...state, data: action.payload};
        }
    },
    immer: {},
    action: {
        async myDelay({put}, action) {
            await delay(3000);
            await put({type: "changeData", payload: action.payload});
        },
        async asyncChangeData({take}, action) {
            await take({type: "myDelay", payload: action.payload});
        }
    }
})(function() {
    useTab("我的");
    return (
        <div>
            <Hello1 />
            <Hello2 />
            <Hello3 />
        </div>
    );
});
  1. 实现方法参考:

github

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容