某些组件状态共享是存在范围的,并不需要扩大到全局,这时使用基于redux的soul状态模型就显得鸡肋了, 通过制作一个高阶组件让数据共享范围变小,同时让它使用体验与redux相同,这个实现多亏useReducer()的hooks函数。
先来看看使用方法
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>
);
});
- 实现方法参考: