Issue (tl; dr)
Как мы можем создать пользовательский редуктор-редуктор с redux-toolkit 's createSlice ?
Есть ли более простое, рекомендованное, более элегантное или просто другое решение, чем попытка, представленная в этом вопросе?
Подробности
Пример пользовательский редуктор-редуктор выглядит следующим образом (упрощенно):
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;
}
Можно упростить редукторы с помощью функции createSlice
redux -toolkit (основано на инструментарии redux-toolkit Руководство по использованию ):
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
Однако в начале редуктора orx-редуктора нам необходимо создать сеанс
const session = orm.session(dbState);
затем мы выполняем магию редуктора-редуктора c, и в конце нам нужно вернуть состояние
return session.state;
Таким образом, мы пропускаем что-то вроде beforeEachReducer
и afterEachReducer
методы в createSlice
для добавления этой функциональности.
Решение (попытка)
Мы создали withSession
функцию более высокого порядка, которая создает сеанс и d возвращает новое состояние.
const withSession = reducer => (state, action) => {
const session = orm.session(state);
reducer(session, action);
return session.state;
}
Нам нужно обернуть каждую логику редуктора c в это 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