Руководство по стилю Redux состояния:
Избегайте помещения несериализуемых значений, таких как обещания, символы, карты / наборы, функции или экземпляры классов в состояние хранилища Redux или отправленные действия. Это гарантирует, что такие возможности, как отладка с помощью Redux DevTools, будут работать должным образом. Это также гарантирует, что UI будет обновляться должным образом.
Immer - Complex-Objects
Каждый другой объект должен использовать непроницаемый символ для маркировки сам по себе совместим с иммером. Когда один из этих объектов изменяется внутри производителя, его прототип сохраняется между копиями.
class Foo {
[immerable] = true // Option 1
constructor() {
this[immerable] = true // Option 2
}
}
Foo[immerable] = true // Option 3
Я знаю, что могу иметь редуктор экземпляра класса ... но должен Я?
Я предполагаю, что опасность заключается в том, что путешествия во времени и Redux DevTools могут быть сломаны, но immer
защитит от любых мутаций вне редуктора.
Пример: :
import { immerable } from "immer";
class MyClass {
constructor() {
this[immerable] = true;
this.data = [];
}
addData(row = "") {
this.data.push(row);
}
prettyPrint() {
this.data.map((txt, index) => console.log(`Row ${index}: ${txt}`));
}
}
const example = createSlice({
name: "example",
initialState: new MyClass(),
reducers: {
addItem: (state, action) => {
state.addData(action.payload);
}
}
});
let state = example.reducer(undefined, example.actions.addItem("Test"));
console.log(state.prettyPrint());
state = example.reducer(state, example.actions.addItem("Test Me too"));
console.log(state.prettyPrint());
console.log(state);
//Will error
// state.addData('Will Error');
Причина этого? У нас есть комплексные бизнес-логи c внутри больших классов. Как и в примере prettyPrint
, у нас есть некоторые сложные функции, которые инкапсулированы в экземпляре класса, который мы используем во всех приложениях для реагирования.
Моя другая идея для подхода - создать экземпляр и сериализовать внутри редуктора, чтобы что json представление экземпляров нашего класса всегда хранится только внутри редукторов. Если я могу избежать необходимости выполнять создание экземпляра -> сериализовать каждое действие и иметь доступ к служебным функциям в дереве состояний, это было бы предпочтительнее.