簡體   English   中英

批量更新規范化的Redux狀態

[英]Bulk updating normalized Redux state

假設我已經像這樣規范化狀態(使用normalizr)

entities: {
  todos: {
    'aaa': {
      id: 'aaa',
      text: 'Todo A',
      completed: false
    },
    'bbb': {
      id: 'bbb',
      text: 'Todo B',
      completed: false
    },
    'ccc': {
      id: 'ccc',
      text: 'Todo C',
      completed: false
    }
  }
}

然后我有一個從服務器獲取ID的動作,已完成。 對於該動作類型,我有這樣的reducer:

const todos = (state = initialState, action) => {
  switch (action.type) {
    case ActionTypes.FETCH_COMPLETED_SUCCESS:
      return {
        ...state,
        todos: action.payload.completedIds.map((id) => {
          return {
            [id]: {
              ...state.todos[id],
              completed: true
            }
          }
        })
      };
    default:
      return state;
  }
};

如果我收到一個帶有''aaa','ccc']的數組(可能是真實應用程序中的數千個項目),我想在單個動作中將“completed”設置為TRUE,是否可能?

我當前的reducer實現不起作用,因為它返回一個對象數組,而原始規范化狀態是ID為關鍵字的對象。

謝謝。

您可以將修改后的待辦事項存儲在對象中,然后使用擴展語法更新它

const todos = (state = initialState, action) => {
  switch (action.type) {
    case ActionTypes.FETCH_COMPLETED_SUCCESS:
      let newTodos = {};
      action.payload.completedIds.forEach((id) => {
          newTodos[id]: {
              ...state.todos[id],
              completed: true
            }
          })
        })
      return {
        ...state,
        todos: {
             ...state.todos,
             ...newTodos
        }
      };
    default:
      return state;
  }
};

我認為這是解決您問題的方法:

const todos = (state = initialState, action) => {
  switch (action.type) {
    case ActionTypes.FETCH_COMPLETED_SUCCESS:
      return {
        ...state,
        todos: Object.keys(action.payload.completedIds).reduce((previous, current) => {
            previous[current] = {
              ...state.todos[current],
              completed: true
            }
            return previous;
          }, {})
        })
      };
    default:
      return state;
  }
};

我使用此解決方案是因為返回一個新對象並保留原始對象

你可以試試這個:

 const todos = (state = initialState, action) => {
  switch (action.type) {
    case ActionTypes.FETCH_COMPLETED_SUCCESS:
      const newState = {};//New Object
      const filterKeys = Object.keys(state).filter( key=>{
        newState[key]=state[key]; //copy
        return completedIds.indexOf(key)!=-1;
      });
      filterKeys.forEach(key=> newState[key].completed = true);
       return newState;
    default:
      return state;
  }
};

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM