Как обновить одно значение внутри определенного элемента массива в сокращении
У меня проблема, когда повторная передача состояния вызывает проблемы ui, и было предложено только обновить определенное значение внутри моего редуктора, чтобы уменьшить количество повторного рендеринга на странице.
это пример моего состояния
{
name: "some name",
subtitle: "some subtitle",
contents: [
{title: "some title", text: "some text"},
{title: "some other title", text: "some other text"}
]
}
и в настоящее время я обновляю его так
case 'SOME_ACTION':
return { ...state, contents: action.payload }
где action.payload
- это целый массив, содержащий новые значения. Но теперь мне просто нужно обновить текст второго элемента в массиве содержимого, и что-то вроде этого не работает.
case 'SOME_ACTION':
return { ...state, contents[1].text: action.payload }
где action.payload
теперь текст, который мне нужен для обновления.
Ответы
Ответ 1
Вы можете использовать Помогать помощникам по невосприимчивости
import update from 'react-addons-update';
// ...
case 'SOME_ACTION':
return update(state, {
contents: {
1: {
text: {$set: action.payload}
}
}
});
Хотя я бы предположил, что вы, вероятно, будете делать что-то более похожее на это?
case 'SOME_ACTION':
return update(state, {
contents: {
[action.id]: {
text: {$set: action.payload}
}
}
});
Ответ 2
Вы можете использовать map
. Вот пример реализации:
case 'SOME_ACTION':
return {
...state,
contents: state.contents.map(
(content, i) => i === 1 ? {...content, text: action.payload}
: content
)
}
Ответ 3
Вам не нужно делать все в одной строке:
case 'SOME_ACTION':
const newState = { ...state };
newState.contents =
[
newState.contents[0],
{title: newState.contnets[1].title, text: action.payload}
];
return newState
Ответ 4
Очень поздно для вечеринки, но вот общее решение, которое работает с каждым значением индекса.
-
Вы создаете и распространяете новый массив от старого массива до index
который хотите изменить.
-
Добавьте данные, которые вы хотите.
-
Создать и распространить новый массив из index
вы хотите изменить, до конца массива
let index=1;// probabbly action.payload.id
case 'SOME_ACTION':
return {
...state,
contents: [
...state.contents.slice(0,index),
{title: "some other title", text: "some other text"},
...state.contents.slice(index+1)
]
}
Ответ 5
В моем случае я сделал что-то подобное, основываясь на ответе Луиса:
...State object...
userInfo = {
name: '...',
...
}
...Reducer code...
case CHANGED_INFO:
return {
...state,
userInfo: {
...state.userInfo,
// I'm sending the arguments like this: changeInfo({ id: e.target.id, value: e.target.value }) and use them as below in reducer!
[action.data.id]: action.data.value,
},
};
Ответ 6
Я считаю, что когда вам нужны такие операции в вашем состоянии Redux, оператор распространения - ваш друг, и этот принцип применим ко всем детям.
Давайте представим, что это ваше государство
const state = {
houses: {
gryffindor: {
points: 15
},
ravenclaw: {
points: 18
},
hufflepuff: {
points: 7
},
slytherin: {
points: 5
}
}
}
И вы хотите добавить 3 очка в Равенкло
const key = "ravenclaw";
return {
...state, // copy state
houses: {
...state.houses, // copy houses
[key]: { // update one specific house (using Computed Property syntax)
...state.houses[key], // copy that specific house properties
points: state.houses[key].points + 3 // update its 'points' property
}
}
}
Используя оператор распространения, вы можете обновить только новое состояние, оставив все остальное без изменений.
Пример взят из этой удивительной статьи, вы можете найти практически все возможные варианты с отличными примерами.