【发布时间】:2020-04-24 10:45:48
【问题描述】:
问题(tl;dr)
我们如何用redux-toolkit 的createSlice 创建一个custom redux-orm reducer?
有没有比这个问题中提供的尝试更简单、推荐、更优雅或其他的解决方案?
详情
custom redux-orm reducer 的示例如下所示(简化):
function ormReducer(dbState, action) {
const session = orm.session(dbState);
const { Book } = session;
switch (action.type) {
case 'CREATE_BOOK':
Book.create(action.payload);
break;
case 'REMOVE_AUTHOR_FROM_BOOK':
Book.withId(action.payload.bookId).authors.remove(action.payload.authorId);
break;
case 'ASSIGN_PUBLISHER':
Book.withId(action.payload.bookId).publisherId = action.payload.publisherId;
break;
}
return session.state;
}
可以使用redux-toolkit 的createSlice 函数来简化reducer(基于redux-toolkit usage-guide):
const ormSlice = createSlice({
name: 'orm',
initialState: [],
reducers: {
createBook(state, action) {},
removeAuthorFromBook(state, action) {},
assignPublisher(state, action) {}
}
})
const { actions, reducer } = ormSlice
export const { createBook, removeAuthorsFromBook, assignPublisher } = actions
export default reducer
但是,在redux-orm reducer的开始我们需要创建一个会话
const session = orm.session(dbState);
然后我们使用 redux-orm reducer 魔法,最后我们需要返回状态
return session.state;
所以我们错过了 createSlice 中的 beforeEachReducer 和 afterEachReducer 之类的方法来添加此功能。
解决方案(尝试)
我们创建了一个withSession 高阶函数,用于创建会话并返回新状态。
const withSession = reducer => (state, action) => {
const session = orm.session(state);
reducer(session, action);
return session.state;
}
我们需要将每个 reducer 逻辑包装在这个 withSession 中。
import { createSlice } from '@reduxjs/toolkit';
import orm from './models/orm'; // defined elsewhere
// also define or import withSession here
const ormSlice = createSlice({
name: 'orm',
initialState: orm.session().state, // we need to provide the initial state
reducers: {
createBook: withSession((session, action) => {
session.Book.create(action.payload);
}),
removeAuthorFromBook: withSession((session, action) => {
session.Book.withId(action.payload.bookId).authors.remove(action.payload.authorId);
}),
assignPublisher: withSession((session, action) => {
session.Book.withId(action.payload.bookId).publisherId = action.payload.publisherId;
}),
}
})
const { actions, reducer } = ormSlice
export const { createBook, removeAuthorsFromBook, assignPublisher } = actions
export default reducer
【问题讨论】:
标签: redux redux-orm redux-toolkit