Позволяет ли Immer хранить экземпляры классов в редукторе redux? - PullRequest
1 голос
/ 26 мая 2020

Руководство по стилю 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 представление экземпляров нашего класса всегда хранится только внутри редукторов. Если я могу избежать необходимости выполнять создание экземпляра -> сериализовать каждое действие и иметь доступ к служебным функциям в дереве состояний, это было бы предпочтительнее.

1 Ответ

1 голос
/ 26 мая 2020

Вы вообще не должны использовать для этого класс.

Просто сохраните свой data как JS объект или массив напрямую и используйте селекторы , чтобы сделать красивую печать.

...