2017-01-30 3 views
1

Если мое состояние выглядит следующим образом:Redux Deep Copying Array, даже если они остаются неизменными?

const initialState = { 
    color: 'blue', 
    sizes: ['S', 'M', 'L'], 
} 

И я хочу, чтобы изменить цвет, мой редуктор должен вернуть это право:

return { ...state, color: newColor }; 

Но не государство по-прежнему ссылаются на старый массив? Это считается мутацией, хотя я не изменяю массив? Будет ли это лучше?

return { 
    ...state, 
    color: newColor, 
    sizes: state.map.sizes(size => size) 
} 

А что, если массив содержит объекты?

const initialState = { 
    color: 'blue', 
    sizes: [ 
    { color: 'red', size: 'S' }, 
    { color: 'green', size: 'M' }, 
    { color: 'blue', size: 'L' } 
    ], 
} 

Означает ли это, что я должен сделать это, чтобы избежать мутации состояния?

return { 
    ...state, 
    color: newColor, 
    sizes: state.map.sizes(item => { ...item }) 
} 



Кроме того, есть причина Object.assign и оператор распространения предпочтительнее делать JSON.stringify и JSON.parse?

ответ

1

Нет, это не мутация. То, что вы делаете, прекрасно.

Посмотрите:

const obj1 = { 
    a: 1, 
    b: 2, 
    c: 3 
}; 

const obj2 = { 
    ...obj1, 
    c: 4 
}; 

Ни в какое время является любой член первого объекта изменяется, когда второй объект создается.

В ситуации Redux (или действительно, в любое время в кодовой базе FP с чистыми функциями) нет вреда в обмене ссылками, если ссылки равны только для чтения.

Это означает, что когда вы создаете новый объект, его свойства могут с радостью быть прямыми ссылками на свойства другого объекта, если вы не мутируете какие-либо под-свойства (поскольку эти вспомогательные свойства будут общими объектами).

+0

Вот что я понял через некоторое время. Неважно, если и старое, и новое состояние ссылаются на один и тот же массив, потому что я не изменял его. Я все еще могу выполнить проверки равенства и вернуться к предыдущему состоянию, если это необходимо. – epiqueras

+0

@epiqueras и вот почему это отличная практика, если вы выражаете дисциплину, чтобы копировать и ничего не изменять, она предлагает очень быструю и легкую проверку личности. Есть, конечно, библиотеки разных вкусов (ImmutableJS и различные библиотеки объективов FP), но если вы по своему усмотрению или у вас есть страстная команда, нет причин, по которым вы не можете использовать объекты Vanilla JS таким образом. Особенно с будущими шаблонами останова/распространения объектов. – Norguard

+0

Да, я могу полностью увидеть, что это становится болью при работе с сложным массивом и вложенными изменениями свойств. Я только что проверил некоторые из этих библиотек и, безусловно, буду использовать их, если мне когда-нибудь понадобится выполнить более сложные операции. Я также пытаюсь составить редукторы и сохранить состояние как можно более плоским, чтобы избежать его. – epiqueras