2015-10-15 43 views
29

Hãy cùng tôi ở đây vì câu hỏi này liên quan đến ứng dụng thử nghiệm đầu tiên của tôi bằng React, Redux hoặc phản ứng-redux. Tài liệu đã giúp tôi vượt xa và tôi có một ứng dụng ngân hàng giả hoạt động chủ yếu. đối tượng trạng thái của tôi trông gần như thế này:Cập nhật cửa hàng React-redux nhưng React không

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

tôi chỉ có hai hành động:

1. CHANGE_HASH (như trong url băm). Hành động này luôn hoạt động như mong đợi và tất cả các trình giảm tốc hiện đang cập nhật state.activePageId (vâng, tôi nhân bản đối tượng trạng thái và không sửa đổi nó). Sau khi hành động, tôi có thể thấy trạng thái đã thay đổi trong cửa hàng Redux và tôi có thể thấy rằng React đã được cập nhật.

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

2. ADD_TRANSACTION (gửi biểu mẫu). Hành động này không bao giờ cập nhật React, nhưng nó luôn cập nhật kho lưu trữ Redux. Bộ giảm tốc cho hành động này đang cập nhật state.accounts [0] .balance và nó thêm một đối tượng giao dịch vào mảng state.accounts [0] .transactions. Tôi không nhận được bất kỳ lỗi nào, React không cập nhật. BAO GIỜ, nếu tôi gửi một hành động CHANGE_HASH, React sẽ bắt kịp và hiển thị tất cả các cập nhật trạng thái ADD_TRANSACTION đúng cách.

chức năng addTransaction (giao dịch, cân bằng, tài khoản) { trở lại { loại: "ADD_TRANSACTION", tải trọng: { giao dịch: giao dịch, cân bằng: cân bằng, tài khoản: Tài khoản } } }

giảm My ...

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 My

012.
function select(state) { 
    return state; 
} 

Tôi thiếu gì ở đây? Tôi có ấn tượng rằng React được cho là sẽ cập nhật khi cửa hàng Redux được cập nhật.

Github repo: https://github.com/curiousercreative/bankDemo Triển khai: http://curiousercreative.com/demos/bankDemo/

tái bút: Tôi nói dối về việc không có bất kỳ lỗi nào. Tôi có một số cảnh báo "" Cảnh báo: Mỗi đứa trẻ trong một mảng hoặc trình lặp nên có một "chìa khóa" chống đỡ độc đáo ... "Tôi đã cung cấp cho họ một chìa khóa prop thiết lập để chỉ số của nó. Tôi nghi ngờ rằng có bất cứ điều gì để làm gì với vấn đề của tôi mặc dù

+1

Hmm, tôi nghĩ hai điều sẽ giúp thu hẹp các lỗi: 1) sử dụng [Redux-logger] (https://github.com/fcomb/redux-logger) để xem những gì đang thay đổi khi hành động xảy ra 2) đăng mã giảm tốc, hành động và mã mapStateToProps của bạn. – Cheng

+0

Thật không may, tôi đã không thể nhận được redux-logger làm việc, nhưng tôi đã đăng nhập những thứ trên của riêng tôi và mọi thứ đang làm việc như mong đợi ở đó. Tôi sẽ cập nhật câu hỏi ngay bây giờ với bộ giảm tốc, hành động và mapStateToProps. – curiouser

+0

React xác định xem tiểu bang có thay đổi không? Có lẽ vì sự thay đổi khá sâu trong đối tượng nhà nước và sự thay đổi quá nhỏ nên nó không tái hiện lại? Làm thế nào để phản ứng-redux quyết định liệu khi nào cần cập nhật các đạo cụ React? Tôi chỉ cần đăng xuất giá trị của nhà nước trong mapStateToProps và nó được cập nhật ở đó, chỉ cần không có trong React. – curiouser

Trả lời

44

vấn đề là trong đoạn mã này:..

 // 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; 

Nhân bản đối tượng trạng thái không có nghĩa là bạn có thể biến những đối tượng mà nó được đề cập đến tôi đề nghị bạn để đọc thêm về bất biến vì đây không phải là cách nó hoạt động

Sự cố và giải pháp này được mô tả chi tiết trong tài liệu "Xử lý sự cố" Redux vì vậy tôi khuyên bạn nên đọc chúng.

https://redux.js.org/troubleshooting

Tôi cũng đề nghị bạn để có một cái nhìn vào tấm danh thiếp Shopping dụ trong Flux So sánh cho Redux vì nó cho thấy làm thế nào để cập nhật đối tượng lồng nhau mà không biến đổi chúng trong một cách tương tự như những gì bạn đang yêu cầu.

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

+7

Cảm ơn bạn! Tôi đã đọc qua những tài liệu đó và đã cố gắng bảo vệ đối tượng nhà nước, tuy nhiên sự hiểu lầm của tôi là trong phương pháp Object.assign. Trong khi điều này đã tạo ra một đối tượng mới từ đối tượng ban đầu, nó chỉ là một đối tượng có nghĩa là nhân bản vô tính trong đối tượng trạng thái không được nhân bản nhưng vẫn tham chiếu các đối tượng gốc của các đối tượng lồng nhau. Tôi đã không chạy vào thuộc tính này với một hành động khác vì không có đối tượng lồng nhau nào đang được sửa đổi. Viết tốt về nhân bản đối tượng (# 5 là điều đã cho tôi): http://blog.soulserv.net/understanding-object-cloning-in-javascript-part-i/ – curiouser

+7

Đúng vậy. Nói chung bạn không muốn sao chép sâu sắc tất cả mọi thứ mặc dù bởi vì nó là tốn kém. Chỉ cần sao chép các phần bạn thay đổi. Chia tách thành nhiều chức năng để giữ mã duy trì được. Bạn có thể lấy cảm hứng từ ví dụ "giỏ hàng" trong Redux repo. –

Các vấn đề liên quan