У меня есть приложение для реагирования, использующее redux с объектом состояния, который выглядит так:
{
personal: { firstName: 'Lance', lastName: 'Uppercut' },
phones: [
{ id: 1, number: '111-222-3333' },
{ id: 2, number: '444-555-6666' }
]
}
Скажем, произошло действие, изменившее только свойство personal, оставив phones в покое. Нужно ли мне копировать весь массив phones в редуктор или можно оставить его указывающим на старый массив, поскольку он не изменился?
Другими словами, это нормально?
return Object.assign({}, state, {
personal: { firstName: 'Rock', lastName: 'Strongo' },
phones: state.phones
});
или мне тоже нужно скопировать массив?
return Object.assign({}, {
personal: { firstName: 'Rock', lastName: 'Strongo' },
phones: state.phones.map(p => Object.assign({}, p))
});
Это также применимо к ссылкам на объекты. Если phones, где вложенный объект вроде этого
{
personal: { firstName: 'Lance', lastName: 'Uppercut' },
phones: {
'1': { number: '111-222-3333', areaCode: '619' },
'2': { number: '444-555-6666', areaCode: '512' }
}
}
Можно ли оставить новый объект состояния, указывающий на ссылку на старый?





Вы можете обновлять только то, что изменилось, и это содержащие структуры.
Поскольку состояние уже включает phones, а его нет, вам нужно только слить измененный личный:
return Object.assign({}, state, {
personal: { firstName: 'Rock', lastName: 'Strongo' }
});
Или используя распространение объекта:
return {
...state,
personal: { firstName: 'Rock', lastName: 'Strongo' }
};
Лучше всего создать новую копию состояния и изменить только поле, которое вы хотите изменить, а именно:
return {
...state,
personal: { firstName: 'Rock', lastName: 'Strongo' }
});
(Это использование оператора распространения es6, который возвращает новую копию объекта состояния и изменяет только поле personal, которое короче и чище, чем старый способ Object.assign).