6
votes

React redux: impossible de définir sur un enregistrement immuable

J'essaye de mettre à jour mon modèle redux à partir de mon réducteur. Le modèle est une extension d'une classe Immutable Record. J'essaie de mettre à jour l'enregistrement avec la méthode set:

const faqsReducer: Reducer<FaqsState> = (state = null, action: AppActions) => {

  state = new FaqsState();

Le réducteur contient les éléments suivants:

let initial = new FaqsState();

const faqsReducer: Reducer<FaqsState> = (state = initial, action: AppActions) => {

Cependant, cela me donne ce qui suit erreur:

Error: Cannot set on an immutable record.

MISE À JOUR

Lorsque je change le réducteur de:

case ActionTypes.FAQS_GET_AJAX_RECEIVE:
  let response: IFaqsGetResponse = action.payload.response && action.payload.response.response;
  return state.with({
    loading: false,
    items: List(response)
  });


1 commentaires

Sur quelle ligne obtenez-vous l'exception? Est-ce vraiment sur la ligne suivante? this.set ('chargement', props.loading);


4 Réponses :


0
votes

Eh bien, c'est immuable . Lorsque vous avez appelé la fonction with , vous avez muté l'objet, violant ainsi sa seule contrainte.
Pour éviter cela, vous devez créer une nouvelle instance avec les nouvelles valeurs et la renvoyer au magasin.


1 commentaires

Quand je regarde la documentation: immutable-js.github.io/immutable -js / docs / # / Record , je vois que Set est une méthode d'enregistrement et est censé fonctionner comme je l'ai implémenté



0
votes

Faites simplement:

with(props: IFaqsState) {
  return this.set('loading', props.loading);
}


1 commentaires

malheureusement cela me donne la même erreur. ce qui est étrange puisque la méthode set est censée renvoyer une nouvelle instance



0
votes

Essayez d'utiliser l'approche suivante pour mettre à jour votre réducteur Définissez un état

case ActionTypes.FAQS_GET_AJAX_RECEIVE:
    let response: IFaqsGetResponse = action.payload.response && 
    action.payload.response.response;
    return {...initialState.list, loading: false, items:List(response)}

Puis en cas de changement,

let initialState = {
   // Create an immutable object 
   list: { loading: true, list: []}
};


0 commentaires

0
votes

Dans votre mise à jour, chaque fois que votre réducteur est appelé, un nouveau state = new FaqsState (); est créé.

Dans votre implémentation précédente, let initial = new FaqsState ( ); est créé une fois et hors de portée pour la fonction de réduction, et donc la même référence / enregistrement est recyclée pour tous les appels suivants du réducteur. Lorsque ce réducteur est appelé pour la première fois, le initial est vide et peut être appelé avec avec pour définir la valeur de initial , mais après cela, initial est déjà définie, et le deuxième appel sur le réducteur tentera de "remplacer" la valeur de initial , ce qui entraînera une exception.

Cependant, je vous suggère de signer ceci par souci de concision et d'exactitude

const faqsReducer: Reducer<FaqsState> = (state =(new FaqsState()), action: AppActions) => {

car votre réducteur mis à jour ne peut pas obtenir la valeur de l'état précédent.


0 commentaires