redux-effect-models v1.5.0
redux-effect-models
如果你使用过 dva 或者 vuex 很容易就能理解这是什么。
此插件没有改变 redux,只是提供了一种不同于官方推荐的数据流构建方式。
采用了以 Model 为单位,将数据分割成多个模块进行管理,每个 Model 负责管理好自己的内部状态,降低了数据流管理的复杂度。
- 支持
Typescript - 支持 异步
Action - 支持 中间件
- 支持 动态添加
Model
安装
$ yarn add redux-effect-models或者
$ npm i redux-effect-models使用
- 创建一个最简单的
Model
// src/store/models/counter.js
export default {
namespace: 'counter',
state: {
count: 0,
},
effects: {
async addCount(context, action) {
await context.delay(300);
context.dispatch({
type: 'saveCount',
payload: context.state.count + action.payload
})
}
},
reducers: {
saveCount(state, action) {
return {
...state,
count: action.payload,
};
},
},
}- 调用
reduxEffectModels初始化状态
// src/store/models/index.js
import { reduxEffectModels } from 'redux-effect-models';
import counter from './counter';
const { reducer, state, effect } = reduxEffectModels([counter]);
export {
// Redux Reducer
reducer,
// 所有 `Model State` 合并出的初始状态
state,
// Redux Middleware
effect
}- 创建
Redux Store时, 将调用reduxEffectModels返回的reducerstateeffect传入createStore
// src/store/index.js
import { createStore, applyMiddleware } from 'redux';
import { reducer, state, effect } from './models';
const store = createStore(reducer, state, applyMiddleware(effect));
export default store;- 修改
store中的状态,action type就是Model的namespace+/+key
// xxx.js
import store from './store';
console.log(store.getState().counter.count) // 0
// 触发一个 reducer
store.dispatch({
type: 'counter/saveCount',
payload: 100,
});
console.log(store.getState().counter.count) // 这个时候 counter 中的 count 等于 100
// 触发一个 effect 会返回一个 Promise
const p = store.dispatch({
type: 'counter/addCount',
payload: 100,
});
p.then(() => {
console.log(store.getState().counter.count) // 这个时候 counter 中的 count 等于 200
})概念
Model
Model 完整结构如下所示
{
namespace: string; // 用于识别当前 Model
state: { [key: string]: any }; // 用于合并 rootState
middlewares?: { [key: string]: Middleware[] }; // 用于处理通用异步逻辑
effects?: { [key: string]: Effect }; // 用于处理异步逻辑
reducers: { [key: string]: Reducer }; // 用于同步修改状态
}Reducer
类型: (state, action) => Object
Reducer 必须是一个纯函数, 修改状态的唯一方式是提交一个 Reducer, 接收 state 和 action 两个参数, 返回修改后的状态
reducers: {
test(state, action) {
return {
...state,
value: action.payload
}
}
}Effect
类型: (context, action) => Promise<void>
context
{
namespace, // 当前 Model 的 namespace
state, // 当前 Model 的 state
rootState, // 所有 Model 的 state
dispatch, // action type 自动拼接上当前 Model 的 namespace
rootDspatch, // 原始 dispatch
delay, // 延时器
}Effect 用于处理异步逻辑,必须返回一个 Promise。可以包含任意异步操作,比如异步请求。在 Effect 中想要修改状态,只能通过提交 Reducer 完成。
effects: {
async test(context, action) {
// 可以触发 reducer 修改状态
context.dispatch({
type: 'reducer'
});
// 也可以触发其他的 effect
await context.dispatch({
type: 'effect'
});
}
}Middleware
类型: (context, action, next) => Promise<void>
Middleware 用于处理通用异步逻辑,必须返回一个 Promise,接收 context action next 参数。全局中间件会作用于所有 Effect,Model 内部中间件只会作用于指定的 Effect。多个中间件执行顺序: 从左到右,从全局到局部,数据流向遵循洋葱模型。
- 完成一个最简单的中间件
async function middleware(context, action, next) {
console.log('start'); // 前置逻辑
await next(); // 必须调用 next 执行后续的 middleware 或者 effect
console.log('end') // 后置逻辑
}- 全局使用
import { addMiddlewares } from 'redux-effect-models';
addMiddlewares([middleware]);Model内使用,Middleware key和被作用的Effect key必须保持一致
middlewares: {
test: [middleware] // key = test
},
effects: {
async test() { // key = test
...
}
}API
reduxEffectModels(models, middlewares?)
参数
reduxEffectModels 接收两个参数
models:Model组成的数组(必传)middlewares: 全局Middleware组成的数组(可选)
import { reduxEffectModels } from 'redx-effect-models';
const { reducer, state, effect } = reduxEffectModels([model1, model2, model3, ...], [middleware1, middleware2, middleware3, ...]);返回值
reduxEffectModels 返回含有 reducer state effect 这三个属性的对象, 这三个属性都是 Redux createStore() 的参数
reducer: Redux Reducerstate: 所有Model State合并出的初始状态effect: Redux Middleware
import { createStore, applyMiddleware } from 'redux';
const store = createStore(reducer, state, applyMiddleware(effect));registerModel(model)
参数
model 需要注册的 Model
import { ActionType, registerModel } from 'redux-effect-models';
registerModel(model);
// 注册后需要调用 dispatch 同步数据
store.dispatch({
type: ActionType.REGISTER
});unregisterModel(namespace)
参数
namespace 需要被取消注册 Model 的 namespace
import { ActionType, unregisterModel } from 'redux-effect-models';
unregisterModel(namespace);
// 取消注册后需要调用 dispatch 同步数据
store.dispatch({
type: ActionType.UNREGISTER
});addMiddleware(middleware)
参数
middleware 需要添加的 Middleware
import { addMiddleware } from 'redux-effect-models';
addMiddleware(middleware);removeMiddleware(middleware)
参数
middleware 需要删除的 Middleware
import { removeMiddleware } from 'redux-effect-models';
removeMiddleware(middleware);5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago