[javascript] Comment mettre des méthodes sur les objets en état Redux?



0 Answers

La réponse de Dan est bien sûr correcte quant à la façon dont vous devriez utiliser redux lors de l'écriture d'une application à partir de zéro. Ma réponse est basée sur une situation de motivation non idéale qui peut être similaire à la situation des OP et comment je pense à y faire face.

Je me retrouve à essayer de créer une application redux qui dépend de bibliothèques tierces dans le redux réducteur qui effectuent des opérations sur des objets d'entrée avec des méthodes, et je voulais garder ces objets d'entrée dans l'état redux. Voici ma situation motivante en pseudo-code, et comment je la «résous» en utilisant la méthode assign de lodash:

// Library A is a large 3rd party library I don't want to change
// Library A expects instances of MyClass to have a method 'complexOperation', and also to have property 'a'
LibraryA = class {
  static reliesOnComplexOperation(myClassInstance) {
    if (myClassInstance.complexOperation() && myClassInstance.a < 100) {
      return true;
    } else {
      return false;
    }
  }
}

// MyClass is my own class that I control, and I want to store it's state and make changes to it using the redux reducer.
MyClass = class {
  constructor() {
    this.a = 0;
  }
  myComplexOperation() {
    return a > 10;
  }
}

//and here is my redux reducer, making use of Library A
function reducer(state, action) {
  switch (action.type) {
    case CHANGE_MY_CLASS:
      const myClassInstancePlain = state.myClassInstance;
      // redux has converted myClassInstance into a plain object with no methods, so we need to create a new instance of MyClass, and assign property values from the plain object to the new instance. Using the assign function from lodash library to achieve this - likely not the most efficient way
      const myClassInstance = _.assign(new MyClass(), myClassInstancePlain);

      // now I can pass myClassInstance off to LibraryA, and the complexOperation method will be available
      if (LibraryA.reliesOnComplexOperation(myClassInstance)) {
        myClassInstance.a = 50;
      }
      // I can return myClassInstance as part of the new state, and redux will convert it to a plain object
      return {
        ...state,
        myClassInstance
      };
    default:
      return state;
  }
}

Donc, cet exemple montre une façon d'incorporer des objets avec des méthodes dans l'état redux en tant qu'objets simples, puis en rajoutant les méthodes afin qu'elles puissent être utilisées dans le réducteur de redux. J'adorerais entendre les pensées de Dan ou de quelqu'un d'autre sur ce modèle ou comment cela pourrait être mieux fait. J'ai vu Dan poster à plusieurs endroits que stocker des objets avec des méthodes est une mauvaise idée en redux, donc le but ici est de trouver un moyen de stocker l'objet en tant qu'objet simple et d'attacher les méthodes quand vous en avez besoin d'une manière efficace .

Question

Selon l'état de docs de l'application de réaction doit être quelque chose de sérialisable. Qu'en est-il des classes alors?

Disons que j'ai une application ToDo. Chacun des objets Todo a des propriétés comme le name , la date etc. Maintenant, je veux avoir des méthodes sur les objets qui ne sont pas sérialisables. C'est à dire Todo.rename() qui renommerait todo et ferait beaucoup d'autres choses.

Pour autant que je comprenne je peux avoir la fonction déclarée quelque part et rename(Todo) ou peut-être passer cette fonction via les accessoires this.props.rename(Todo) au composant.

J'ai 2 problèmes avec déclarer .rename() quelque part: 1) Où? En réducteur? Il serait difficile de trouver toutes les méthodes d' would be instance quelque part dans les réducteurs autour de l'application. 2) Passer cette fonction autour. Vraiment? devrais-je le passer manuellement de tous les composants de niveau supérieur via Et chaque fois que j'ai plus de méthodes ajouter une tonne de passe-partout juste pour le transmettre? Ou fais toujours et espère que je n'ai jamais qu'une seule méthode de renommer pour un type d'objet. Pas Todo.rename() Task.rename() et Event.rename()

Cela me semble idiot. L'objet devrait savoir ce qui peut être fait et de quelle manière. N'est-ce pas?

Qu'est-ce qui me manque ici?




Related