2017-11-13 4 views
3

Sagen wir, ich Zustand wie dieses (mit normalizr) normalisiert habenBulk-Aktualisierung normalisierte Redux Zustand

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 
    } 
    } 
} 

Dann habe ich eine Aktion, die Array von IDs vom Server abruft, die abgeschlossen sind. Aus diesem Aktionstyp habe ich Minderer wie folgt aus:

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

Wenn ich ein Array empfangen mit [ ‚aaa‘, ‚ccc‘] (Tausende von Artikeln in der realen Welt app sein könnte), ich setzen wollen " abgeschlossen "zu den jeweiligen Todos in einer einzigen Aktion, ist es möglich?

Meine aktuelle Implementierung von Reducer funktioniert nicht, da sie ein Array von Objekten zurückgibt, während der ursprüngliche normalisierte Zustand Objekt mit IDs als Schlüssel ist.

Danke.

Antwort

3

Sie konnten die modifizierten todos in einem Objekt speichern und sie dann wie die Ausbreitung Syntax aktualisieren

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; 
    } 
}; 
+0

Dies funktionierte, musste nur einen kleinen Syntaxfehler beheben. newTodos [ID]: {...} zu newTodos [ID] = {...} – Razz

+0

Fühlen Sie sich frei, die Antwort zu bearbeiten. –

0

ich denke, das ist die Lösung für Ihr Problem ist:

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

ich diese Lösung verwendet da ein neues Objekt zurückgegeben wird und das ursprüngliche Objekt unverändert bleibt

0

Sie können versuchen:

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; 
    } 
}; 
Verwandte Themen