web-dev-qa-db-fra.com

Les mises à jour du magasin React-redux mais React ne fonctionne pas

Restez avec moi ici car cette question concerne ma première application de test utilisant soit React, Redux ou react-redux. Les docs m'ont amené loin et j'ai une application de simulation bancaire qui fonctionne principalement. Mon objet d'état ressemble à peu près à ceci:

{
 activePageId: "checking",
 accounts: [
  checking: {
    balance: 123,
    transactions: [
      {date, amount, description, balance}
    ]
  }
 ]
}

Je n'ai que deux actions:

1. CHANGE_HASH (comme dans le hachage de l'URL). Cette action fonctionne toujours comme prévu et tout ce que le réducteur effectue consiste à mettre à jour le fichier state.activePageId (oui, je clone l'objet state sans le modifier). Après l'action, je peux voir que l'état a changé dans le magasin Redux et que React a été mis à jour.

function changeHash(id) {
        return {
            type: "CHANGE_HASH",
            id: id
        }
}

2. ADD_TRANSACTION (soumission du formulaire). Cette action ne met jamais à jour React, mais met toujours à jour le magasin Redux. Le réducteur de cette action met à jour state.accounts [0] .balance et ajoute un objet de transaction au tableau state.accounts [0] .transactions. Je ne reçois aucune erreur, React n'est pas mis à jour. CEPENDANT, si j'envoie une action CHANGE_HASH React rattrapera et affichera tous les L'état ADD_TRANSACTION est mis à jour correctement.

fonction addTransaction (transaction, solde, compte) {return {type: "ADD_TRANSACTION", charge utile: {transaction: transaction, solde: solde, compte: compte}}}

Mon réducteur ...

function bankApp(state, action) {
    switch(action.type) {
        case "CHANGE_HASH":
            return Object.assign({}, state, {
                activePageId: action.id
            });
        case "ADD_TRANSACTION":
        // get a ref to the account
            for (var i = 0; i < state.accounts.length; i++) {
                if (state.accounts[i].name == action.payload.account) {
                    var accountIndex = i;
                    break;
                }
            }

        // is something wrong?
            if (accountIndex == undefined)  {
                console.error("could not determine account for transaction");
                return state;
            }

        // clone the state
            var newState = Object.assign({}, state);

        // add the new transaction
            newState.accounts[accountIndex].transactions.unshift(action.payload.transaction);

        // update account balance
            newState.accounts[accountIndex].balance = action.payload.balance;

            return newState;
        default:
            return state;
    }

Mon mapStateToProps

function select(state) {
    return state;
}

Qu'est-ce que j'oublie ici? J'ai l'impression que React est censé être mis à jour lorsque le magasin Redux est mis à jour.

Repo Github: https://github.com/curiousercreative/bankDemo Déploiement: http://curiousercreative.com/demos/bankDemo/

p.s. J'ai menti sur le fait de ne pas avoir d'erreur. J'ai un certain nombre d'avertissements "" Attention: chaque enfant d'un tableau ou d'un itérateur doit avoir un "accessoire" clé unique ... "Je leur donne déjà un accessoire principal à son index. Je doute que cela ait quelque chose à voir avec faire avec mon problème si.

40
curiouser

Le problème est dans ce morceau de code:

// clone the state
var newState = Object.assign({}, state);         

// add the new transaction

newState.accounts[accountIndex].transactions.unshift(action.payload.transaction);

// update account balance
newState.accounts[accountIndex].balance = action.payload.balance;

Cloner l'objet d'état ne signifie pas que vous pouvez muter les objets auxquels il fait référence. Je vous suggère de lire davantage sur l’immutabilité car ce n’est pas ainsi que cela fonctionne.

Ce problème et sa solution sont décrits en détail dans la documentation "Dépannage" de Redux. Je vous suggère donc de les lire.

https://redux.js.org/troubleshooting

Je vous suggère également de jeter un coup d'oeil à l'exemple de carte d'achat dans Flux Comparison for Redux, car il montre comment mettre à jour des objets imbriqués sans les muter de la même manière que ce que vous demandez.

https://github.com/voronianski/flux-comparison/tree/master/redux

56
Dan Abramov