在此请忍受,因为这个问题与我使用React,Redux或react- redux的第一个测试应用有关。Docs使我步入正轨,并且我有一个可以正常工作的模拟银行应用程序。我的状态对象大致如下所示:
{ activePageId: "checking", accounts: [ checking: { balance: 123, transactions: [ {date, amount, description, balance} ] } ] }
我只有两个动作:
1. CHANGE_HASH(如网址哈希中所示)。此操作始终按预期工作,而reducer所做的只是更新state.activePageId(是的,我正在克隆状态对象而不是对其进行修改)。完成该操作后,我可以看到Redux存储中的状态已更改,并且可以看到React已更新。
function changeHash(id) { return { type: "CHANGE_HASH", id: id } }
2. ADD_TRANSACTION(表单提交)。该操作从不更新React,但始终更新Redux存储。该操作state.accounts[0].balance的state.accounts[0]简化程序正在更新,并将事务对象添加到数组.transactions中。我没有收到任何错误,React只是没有更新。但是,如果我派遣一个CHANGE_HASH actionReact,它将赶上并ADD_TRANSACTION正确显示所有状态更新。
state.accounts[0].balance
state.accounts[0]
CHANGE_HASH action
ADD_TRANSACTION
function addTransaction(transaction, balance, account) { return { type: "ADD_TRANSACTION", payload: { transaction: transaction, balance: balance, account: account } } }
我的减速机
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; }
我的mapStateToProps
function select(state) { return state; }
我在这里想念什么?我的印象是React应该随着Redux store更新而更新。
Redux store
Github仓库:
部署银行演示
ps我撒谎说没有任何错误。我确实有很多警告
“”警告:数组或迭代器中的每个子代都应具有唯一的“键”属性…“
我已经给他们prop设置了索引的键。我怀疑这与我的问题有关系。
prop
问题出在这段代码中:
// 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;
克隆状态对象并不意味着您可以对其所引用的对象进行突变。我建议您阅读有关不变性的更多信息,因为这不是它的工作原理。
这个问题及其解决方案在Redux“疑难解答”文档中进行了详细说明,因此建议您阅读它们。
https://redux.js.org/问题排查
我还建议您看一下Redux的Flux比较中的Shopping Card示例,因为它显示了如何更新嵌套对象而不以与您要的类似的方式对嵌套对象进行变异。
https://github.com/voronianski/flux- comparison/tree/master/redux