问题(tl;博士)
我们如何使用redux-toolkit的createSlice创建一个自定义的 redux-orm reducer?
有没有比这个问题中提供的尝试更简单、推荐、更优雅或只是其他解决方案?
细节
自定义 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-toolkitcreateSlice
的功能来简化 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 的开始我们需要创建一个 session
const session = orm.session(dbState);
然后我们使用我们的 redux-orm reducer 魔法,最后我们需要返回状态
return session.state;
所以我们错过了添加此功能的类似方法beforeEachReducer
和afterEachReducer
方法。createSlice
解决方案(尝试)
我们创建了一个withSession
创建会话并返回新状态的高阶函数。
const withSession = reducer => (state, action) => {
const session = orm.session(state);
reducer(session, action);
return session.state;
}
我们需要将每个 reducer 逻辑包装在 this 中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