상태를 다시 렌더링하면 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
지금 업데이트가 필요한 텍스트는 어디에 있습니까 ?
답변
React Immutability 도우미를 사용할 수 있습니다.
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}
}
}
});
답변
사용할 수 있습니다 map
. 다음은 구현의 예입니다.
case 'SOME_ACTION':
return {
...state,
contents: state.contents.map(
(content, i) => i === 1 ? {...content, text: action.payload}
: content
)
}
답변
한 줄로 모든 작업을 수행 할 필요는 없습니다.
case 'SOME_ACTION':
const newState = { ...state };
newState.contents =
[
newState.contents[0],
{title: newState.contnets[1].title, text: action.payload}
];
return newState
답변
파티에 매우 늦었지만 여기에 모든 인덱스 값과 함께 작동하는 일반적인 솔루션이 있습니다.
-
이전 어레이
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)
]
}
최신 정보:
코드를 단순화하기 위해 작은 모듈을 만들었으므로 함수를 호출하기 만하면됩니다.
case 'SOME_ACTION':
return {
...state,
contents: insertIntoArray(state.contents,index, {title: "some title", text: "some text"})
}
더 많은 예를 보려면 저장소를 살펴보십시오.
기능 서명 :
insertIntoArray(originalArray,insertionIndex,newData)
답변
Redux 상태 에서 이런 종류의 작업이 필요할 때 스프레드 연산자가 친구 이며이 원칙은 모든 어린이에게 적용됩니다.
이것이 당신의 상태라고 가정합시다.
const state = {
houses: {
gryffindor: {
points: 15
},
ravenclaw: {
points: 18
},
hufflepuff: {
points: 7
},
slytherin: {
points: 5
}
}
}
그리고 Ravenclaw에 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's properties
points: state.houses[key].points + 3 // update its `points` property
}
}
}
스프레드 연산자를 사용하면 나머지는 그대로두고 새 상태 만 업데이트 할 수 있습니다.
이 놀라운 기사 에서 가져온 예제 , 훌륭한 예제와 함께 가능한 거의 모든 옵션을 찾을 수 있습니다.
답변
제 경우에는 Luis의 대답에 따라 다음과 같이했습니다.
...State object...
userInfo = {
name: '...',
...
}
...Reducer's 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,
},
};
답변
이것이 내 프로젝트 중 하나를 위해 한 방법입니다.
const markdownSaveActionCreator = (newMarkdownLocation, newMarkdownToSave) => ({
type: MARKDOWN_SAVE,
saveLocation: newMarkdownLocation,
savedMarkdownInLocation: newMarkdownToSave
});
const markdownSaveReducer = (state = MARKDOWN_SAVED_ARRAY_DEFAULT, action) => {
let objTemp = {
saveLocation: action.saveLocation,
savedMarkdownInLocation: action.savedMarkdownInLocation
};
switch(action.type) {
case MARKDOWN_SAVE:
return(
state.map(i => {
if (i.saveLocation === objTemp.saveLocation) {
return Object.assign({}, i, objTemp);
}
return i;
})
);
default:
return state;
}
};