2016-08-18 8 views
2

Мой редуктор выглядит следующим образом:Redux Reducer - Как обновить значение объекта без изменения состояния?

const players = (state = {}, action) => { 
    switch (action.type) { 
     case 'UPDATE_PLAYERS_CARDS': 
     return Object.assign({}, state, { 
      [action.player]: { 
      name: state[action.player].name, 
      score: state[action.player].score, 
      cards: action.cards 
      } 
     }) 
     default: 
     return state 
    } 
    } 

    export default players 

В принципе, я просто хочу, чтобы обновить карты игроков, но если я не включать имя и счет, то те, удаляются в новом состоянии.

В идеале мне нужно просто сделать что-то вроде этого: state[action.player].cards = action.cards, но одно из правил - никогда не мутировать состояние.

Метод выше будет работать, но для этого требуется, чтобы я всегда знал структуру данных, поэтому, если я добавлю что-то еще в нее в будущем, мне нужно будет помнить, что возвращаюсь к этому редуктору и добавляю это обратно, чтобы я не теряйте его.

Есть ли лучший способ достичь этого?

Редактировать: Спасибо Vijay за предложение о назначении нескольких объектов. Я закончил работу с этим:

case 'UPDATE_PLAYERS_CARDS': 
    const playerObject = Object.assign(state[action.player], { cards: action.cards }); 
    return Object.assign({}, state, { 
    [action.player]: playerObject 
    }); 

Как это? Сообщите мне, есть ли какие-либо улучшения, которые я могу сделать.

+0

может рассматривать immutable.js и читать на родном реагировании: https://facebook.github.io/react/docs/update.html – dandavis

+0

Вы используете babel? У вас включена предустановка «stage-2»? – QoP

ответ

1

Multiple Object.assign может помочь:

const newState = Object.assign({}, state); 
Object.assign(newState.action.player, { cards: action.cards }); 
+0

Спасибо Vijay. Я отредактировал свой ответ, чтобы отразить мое новое решение, которое вытекало из вашего ответа. Что вы думаете об этом? – Drew

4

Multiple Object.assign методы выглядят некрасиво.

Вы можете сделать:

return { ...state.action.player, cards: action.cards } 

Примечания: Вам необходимы stage-2 столпотворения предустановленного использовать это.

Как только структура данных для обновления становится довольно сложным, вы можете использовать ImmutableJS «s setIn, updateIn методы, чтобы сделать глубокие обновления легко.

+1

'Object.assign' действительно один уродливый mf – Tuna