2017-08-29 71 views
4

我的店看起來是這樣的,在React/Redux還原器中,我如何以不可變的方式更新嵌套數組中的字符串?

{ 
    name: "john", 
    foo: {}, 
    arr: [ 
     { 
     id:101, 
     desc:'comment' 
     }, 
     { 
     id:101, 
     desc:'comment2' 
     } 
    ] 
} 

我textarea的看起來像這樣

<textarea 
    id={arr.id} //"101" 
    name={`tesc:`} 
    value={this.props.store.desc} 
    onChange={this.props.onChng} 
/> 

我的動作是

export const onChng = (desc) => ({ 
    type: Constants.SET_DESC, 
    payload: { 
    desc 
    } 
}); 

我減速

case Constants.SET_DESC: 
    return update(state, { 
    store: { 
     streams: { 
     desc: { $set: action.payload.desc } 
     } 
    } 
}); 

它的工作原理Ø NLY如果ARRY是一個對象,我不得不做出更改流到一個數組,我很困惑我怎麼可以更新到一個數組,還如何得到商店正確的價值。

+1

你怎麼要更新的陣列?修改數組中的元素或添加一個新元素,刪除一個等等? – Li357

+0

我想添加一個新的元素?在{{id:101,here}}旁邊# –

+1

你如何確定ID? – Li357

回答

0

要更新一個數組,我會用immutability helper和做這樣的事情 - 給你的減速器

let store = {"state" : { 
"data": [{ 
    "subset": [{ 
     "id": 1 
    }, { 
     "id": 2 
    }] 
}, { 
    "subset": [{ 
     "id": 10 
    }, { 
     "id": 11 
    }, { 
     "id": 12 
    }] 
}] 
}} 

case Constants.SET_DESC: 
    return update(store, { 
    "state" : { 
    "data": { 
     [action.indexToUpdate]: { 
     "subset": { 
      $set: action.payload.desc 
     } 
     } 
    } 
} 
    }) 
    }); 
+0

這就是我想要實現它..我已經將immutable-helper下載到我的項目中,但是它不工作 - 沒有找到indexToUpdate –

+0

奮力感謝.. –

2

以下來自redux文檔的示例可能會幫助您在用例中如何更新數組中的項目。欲瞭解更多關於這一點,你可以閱讀這裏http://redux.js.org/docs/recipes/StructuringReducers.html

狀態的結構是這樣的

{ 
    visibilityFilter: 'SHOW_ALL', 
    todos: [ 
    { 
     text: 'Consider using Redux', 
     completed: true, 
    }, 
    { 
     text: 'Keep all state in a single tree', 
     completed: false 
    } 
    ] 
} 

和減速器代碼就像下面

function updateObject(oldObject, newValues) { 
    // Encapsulate the idea of passing a new object as the first parameter 
    // to Object.assign to ensure we correctly copy data instead of mutating 
    return Object.assign({}, oldObject, newValues); 
} 

function updateItemInArray(array, itemId, updateItemCallback) { 
    const updatedItems = array.map(item => { 
     if(item.id !== itemId) { 
      // Since we only want to update one item, preserve all others as they are now 
      return item; 
     } 

     // Use the provided callback to create an updated item 
     const updatedItem = updateItemCallback(item); 
     return updatedItem; 
    }); 

    return updatedItems; 
} 

function appReducer(state = initialState, action) { 
    switch(action.type) { 
     case 'EDIT_TODO' : { 
      const newTodos = updateItemInArray(state.todos, action.id, todo => { 
       return updateObject(todo, {text : action.text}); 
      }); 

      return updateObject(state, {todos : newTodos}); 
     } 
     default : return state; 
    } 
} 
+0

我希望做的結構我也問過。意思你如何訪問一個商店陣列 –

+0

'state.todos'是數組 –

+0

不幸的是我不明白..但是謝謝你嘗試 –

1

我如果必須更新商店內數組中的元素,則必須複製數組並複製匹配元素以應用更改。

因此,在第一步中,您的操作應該包含已克隆(和已更改)的對象或對象的ID以及要更改的屬性。

這裏是一個粗略的例子:

export class MyActions { 
    static readonly UPDATE_ITEM = 'My.Action.UPDATE_ITEM'; 

    static updateItem(id: string, changedValues: any) { 
     return { type: MyActions.UPDATE_ITEM, payload: { id, changedValues } }; 
    } 
} 

export const myReducer: Reducer<IAppState> = (state: IAppState = initialState, action: AnyAction): IAppState => { 
    switch (action.type) { 
     case MyActions.UPDATE_ITEM: 
      return { ...state, items: merge(state.items, action.payload) }; 

     default: 
      return state; 
    } 
} 

const merge = (array, change) => { 
    // check if an item with the id already exists 
    const index = array.findIndex(item => item.id === change.id); 
    // copy the source array 
    array = [...array]; 

    if(index >= 0) { 
     // clone and change the existing item 
     const existingItem = array[index]; 
     array[index] = { ...existingItem, ...change.changedValues }; 
    } else { 
     // add a new item to the array 
     array.push = { id: change.id, ...change.changedValues }; 
    } 

    return array; 
} 
+0

將在'array'看起來像你的榜樣嗎? –

+0

'數組'包含你的對象。例如。 '{id:string,desc:string}'。如果你的對象還包含一些其他對象的數組,你必須將上述邏輯嵌套更多一層,而'changedValues'對象也包含一個id屬性。如果這是你的情況,你不知道如何做到這一點,給我一個提示,我會更新我的答案。 – Oliver

相關問題