2017-10-04 61 views
0

我正在學習redux和不可變的,並做一個todo應用程序。React Redux不可改變的狀態不被退回

當我觸發動作方法add_item我得到 「state.push是不是一個函數」

如果我改變這一行

const reducer = (state = initialState, action) => { 

const reducer = (state = new List(), action) => {

我可以添加新的項目,但原始的不顯示,如何解決這個問題?

export const initialState = Map({ 
    items: List (
     Map({ id: 1, content: 'Call mum' }), 
     Map({ id: 2, content: 'Buy cat food' }), 
     Map({ id: 3, content: 'Water the plants' }) 
) 
}); 

const reducer = (state = initialState, action) => { 
    console.log("action.type", action.type); 
    switch (action.type) { 
    case ADD_ITEM: 
     return state.push(Map({ 
     id: nextId++, 
     content: action.content 
     })); 
    default: 
     return state; 
    } 
}; 

回答

0

狀態不是Array的一個實例,因此無法訪問Array.push()方法。國家是一個對象。

首先,我會避免使用任何突變方法,例如, push(),在你的reducer內。如果你必須使用它們,最好把你的行爲定義好。

在這個例子中,我沒有看到「List」或「Map」的效用。注重文字:

const initialState = { 
    items: [ 
      {id: 1, content: 'call mum'}, 
      {id: 2, content: 'call dad'}, 
    ], 
} 

在你的減速機本身,我強烈建議像對象休息傳播一樣不可變的方法。

const reducer = (state = initialState, action) => { 
    switch(action.type){ 
    case "ADD_ITEM": 
     return {...state, items: [...state.items, action.newItem]} 
    } 

    ... 
} 

如果你想養活你的初始狀態,然後可以設置其他情況下,你的減速如下:

switch(action.type){ 
    case "ADD_ITEM": 
     return {...state, items: [...state.items, action.newItem]} 
    case "SET_NEW_LIST": 
     return {...state, items: action.newList} 
    ... 
    } 

並相應地確定另一個動作。或多或少,丹·阿布拉莫夫和其他人鼓勵儘可能簡化你的減速器,並儘可能地將邏輯保留在你的行動中。您的ID增量應該在您的ADD_ITEM操作中處理。

+0

謝謝你爲你的答案,但我想使用immutablejs,如https://www.sitepoint.com/how-to-build-a-todo-app-using-react-redux-and-immutable-js/我是鬆散地跟隨。以上只是我正在構建的測試應用程序的一小部分。將進一步的功能來切換,刪除,過濾狀態。 – Adam

0

您只需調整你的初始狀態那樣:

export const initialState = List ([ 
    Map({ id: 1, content: 'Call mum' }), 
    Map({ id: 2, content: 'Buy cat food' }), 
    Map({ id: 3, content: 'Water the plants' }) 
]) 

如果你想保持像Map{ items: List }你必須重構你的減速和你的狀態更配合物結構:

export const initialState = Map({ 
    items: List ([ 
    //   ^don't forget the brackets here 
     Map({ id: 1, content: 'Call mum' }), 
     Map({ id: 2, content: 'Buy cat food' }), 
     Map({ id: 3, content: 'Water the plants' }) 
    ]) 
}); 

const reducer = (state = initialState, action) => { 
    switch (action.type) { 
    case ADD_ITEM: 
     return state.set('items', state.get('items').push(
     Map({ 
      id: nextId++, 
      content: action.content 
     }) 
    )); 
    default: 
     return state; 
    } 
}; 
相關問題