#reactjs #react-redux
#reactjs #реагировать-redux
Вопрос:
Я назначен на новый проект, который использует React и Redux, и они используют большую часть этого оператора распространения в редукторах. Я уже искал stackoverflow из похожих вопросов, но я все еще не понял этого.
Пример фрагмента reducer из нашего кода и извлекает список искомых записей.
//What is the use of adding ...state in the return
//I tried to remove it but the records returned is still the same
return {
...state,
data: action.orderList,
isLoading: false,
error: null
}
//I also tried to add spread operator on action.orderList but it still returns same data
return {
...state,
data: {...action.orderList},
isLoading: false,
error: null
}
//This is where I am confuse some of their reducers is returning ...state.data too and I am not sure why.
//I tried this on my reducer and it did not update my records properly it did not return the searched
//OrderNumber record only but all records from previous state
return {
...state,
data: {...state.data, ...action.orderList}, // **what is the meaning of doing this?**
isLoading: false,
error: null
}
Ответ №1:
Начните с «что такое редуктор?».
Редуктор принимает предыдущее состояние и действие и возвращает новое состояние (полностью). Состояние также должно оставаться неизменным, поэтому вы не можете напрямую изменять свойства предыдущего состояния.
Общим соглашением для достижения этого (как вы видите здесь) является создание вашего нового объекта состояния путем первого «распространения» свойств старого. Таким образом, вы сохраняете все значения старого состояния. Затем для значений, которые вы хотите фактически обновить, вы размещаете их после, чтобы они перезаписывали значения, распространенные по старому состоянию.
Отказ включить оператор распространения (или другой метод замены неизмененных значений состояния) означает, что вы исключаете их из своего нового объекта состояния, и они исчезают.
Обновления вложенных свойств запускают весь этот процесс заново. Допустим, у вас есть вложенный объект:
const state = {a: {b: 'b', c: 'c'}}
Чтобы обновить этот объект, мы могли бы сначала начать с этого:
const newState = {...state}
Это означает newState
точную копию исходного состояния. Чтобы обновить вложенное свойство b
, у вас может возникнуть соблазн сделать что-то вроде этого:
const newState = {...state, a: {b: 'd'}}
Проблема в том, что вы не заменили свойство c
, поэтому оно исчезает.
Исправьте это, также распространив вложенные объекты:
const newState = {...state, a: {...state.a, b: 'd'}}
Теперь вы можете заметить, что удаление первого ...state
не имеет никакого функционального значения. Это потому, что мы вручную заменили каждое свойство в объекте, поэтому технически это не нужно. Однако вы все равно можете увидеть, что люди включают его либо по привычке, либо для предотвращения проблем при последующем редактировании.
Ответ №2:
spread
Оператор распространяет массив объекта, вместе с которым он используется.
Что он делает, так это распространяет предыдущие значения state
и добавляет или переопределяет новые значения в конечном результате, который возвращается.
Например: предположим, начальное значение state
равно
{
data:[1,2,3],
isLoading:true,
error:"some error",
someOtherKey="test"
}
теперь, если вы запустите, мы будем использовать ваш код,
return {
...state,
data: action.orderList,
isLoading: false,
error: null
}
результат будет
{
someOtherKey="test",
data: action.orderList,
isLoading: false,
error: null,
}
И для этого:
data: {...state.data, ...action.orderList}, // **what is the meaning of doing this?**
Допустим, action.orderList = {id:1}
и state.data={name:"John"}
.
Тогда конечное значение, которому будет присвоено data
значение, будет {id:1,name:"John"}
.