상태가 개체의 배열인 경우 반응 상태를 업데이트하는 중
상태에 있는 오브젝트 배열:
this.state = {
items: [
{id: 1, someattr: "a string", anotherattr: ""},
{id: 2, someattr: "another string", anotherattr: ""},
{id: 3, someattr: "a string", anotherattr: ""},
]
}
ID 속성을 기반으로 항목 배열을 검색하고 개체 속성을 업데이트할 수 있어야 합니다.
는 그 을 는는그 i i i i i i i i i i i로 얻을 수 있다.filtering
★★★★★★★★★★★★★★★★★」finding
id param이라는 ID를 합니다.
문제가 되는 것은 어레이를 업데이트한 후 변환 없이 상태를 업데이트하는 것입니다.
//make sure we're not mutating state directly by using object assign
const items = Object.assign({}, this.state.items);
const match = items.find((item) => item.id === id);
이 시점에서 일치하는 오브젝트가 있으며 오브젝트 스프레드를 사용하여 오브젝트의 속성을 갱신할 수 있습니다.
const matchUpdated = { ...match, someattr: 'a new value'};
를 갱신할 수 요?matchUpdated
첫 번째 검색 조작에 의해 반환된 오브젝트를 덮어쓰게 됩니다.
업데이트 기능은 다음과 같습니다.
updateItem(id, itemAttributes) {
var index = this.state.items.findIndex(x=> x.id === id);
if (index === -1)
// handle error
else
this.setState({
items: [
...this.state.items.slice(0,index),
Object.assign({}, this.state.items[index], itemAttributes),
...this.state.items.slice(index+1)
]
});
}
그리고 이렇게 사용해요.
this.updateItem(2, {someattr: 'a new value'});
징그럽죠?
이런 식으로 복잡한 애플리케이션을 계속 구축하면 전반적으로 큰 골칫거리가 될 것입니다.이러한 문제를 해결하는 데 보다 적합한 redux 또는 기타 플럭스 구현에 대해 알아볼 것을 권장합니다.
Redux는 각각 애플리케이션 상태의 특정 슬라이스에서 작동하는 상태 감소기 개념을 사용합니다.이렇게 하면 깊은 변화에 영향을 미칠 때마다 상태 전체를 수동으로 파헤칠 필요가 없습니다.
Redux의 창시자인 Dan Abramov는 두 개의 비디오 코스를 온라인에서 무료로 이용할 수 있도록 했습니다.댄은 훌륭한 선생님이고, 저는 레독스 패턴과 단 하루만 함께 보낸 후에 편안함을 느꼈습니다.
- https://egghead.io/courses/getting-started-with-redux
- https://egghead.io/courses/building-react-applications-with-idiomatic-redux
함수를 사용하고 싶다면 이렇게 하겠습니다.함수 인수는 항목의 ID, 변경할 속성 및 해당 속성의 새 값입니다.
const [array, setArray] = useState([{
id: 1,
value: "aws",
othervalue: "was"
},
{
id: 2,
value: "goo",
othervalue: "nano"
},
{
id: 3,
value: "micro",
othervalue: "marcro"
},
])
const updateItem = (id, whichvalue, newvalue) => {
let index = array.findIndex(x => x.id === id);
/* This line is only necessary if your element's ID
isn't its position/index in the array or related to it.
In the case that it is, use the ID as the index, or run the function
(binary/hash) that relates the ID to that position/index to find the
index.
*/
if (index !== -1) {
let temporaryarray = array.slice();
temporaryarray[index][whichvalue] = newvalue;
setArray(temporaryarray);
} else {
console.log('no match');
}
}
/* longer version:
var index = array.findIndex(x => x.id === id);
let g = array[index]
g[whichvalue] = newvalue
if (index === -1) {
console.log('no match')
} else {
setArray(
[
...array.slice(0, index),
g,
...array.slice(index + 1)
]
);
}
*/
// how to use the function:
onPress = {
() => updateItem(2, 'value', 'John Lemon')
}
기능 컴포넌트와 useState 훅을 사용하는 경우 오브젝트 전체를 치환하는 것을 꺼리지 않는 한 맵을 쉽게 사용할 수 있습니다.
const [items, setItems] = useState ([
{id: 1, someattr: "a string", anotherattr: ""},
{id: 2, someattr: "another string", anotherattr: ""},
{id: 3, someattr: "a string", anotherattr: ""},
])
setItems (
items.map((item) => {
return item.id === updatedItem.id? updatedItem: item;
})
);
Mulan의 답변에 더하여, 당신은 훨씬 깨끗하고 읽기 쉬운 Object spread를 사용할 수 있습니다.Object.assign()
updateItem(id, itemAttributes) {
var index = this.state.items.findIndex(x=> x.id === id);
if (index === -1)
// handle error
else
this.setState({
items: [
...this.state.items.slice(0,index),
{ ...this.state.items[index], itemAttributes },
...this.state.items.slice(index+1)
]
});
}
그리고 이렇게 사용해요.
this.updateItem(2, {someattr: 'a new value'});
한 줄의 솔루션도 있습니다.
this.setState({items: this.state.items.map(x => x.id === someId ? {...x, attr:'val'} : x)});
중요한 것은 상태를 변환하는 대신 새 어레이를 반환하는 것입니다.
@은 @douglas-gaskell입니다.O(n)
@Mulan의 대답은O(1)
하지만 알고리즘의 복잡도는 n이 커지면 중요합니다.아이템 수가 많을 때는 @Mulan의 답변을 사용하지만, 아이템 수가 적을 때는 이 솔루션을 사용합니다.
상태 배열 개체의 값을 루프하여 상태를 바꿀 수 있습니다.루프에서는 모든 것이 아닌 경우 새로운 값을 적용할 레코드를 결정할 수 있습니다.
this.state = {
items: [
{id: 1, someattr: "a string", anotherattr: ""},
{id: 2, someattr: "another string", anotherattr: ""},
{id: 3, someattr: "a string", anotherattr: ""},
]
}
//답변
const newState = Object.assign({}, this.state);
newState.items.forEach(element => {
element.someattr= "I like it a lot";
});
this.setState(newState);
이와 같은 기능 구성요소에서는 함수에 추가해야 합니다.
const [item,setitem]=usestate([{id_1:null},{id_2:null}])
()=> setitems((prev) => { return { ...prev, id_1: "my change value"} })
이렇게 해서
console.log(items.id_1 == "my change value")
언급URL : https://stackoverflow.com/questions/37662708/updating-react-state-when-state-is-an-array-of-objects
'it-source' 카테고리의 다른 글
리액트 라우터를 사용하여 사용자가 페이지를 떠나는 것을 감지하는 중 (0) | 2023.03.07 |
---|---|
페이지 로드 시 웹 페이지 콘텐츠를 어떻게 div에 로드할 수 있습니까? (0) | 2023.03.07 |
my sql 쿼리를 사용하여 woocommerce에서 완료된 주문을 삭제하는 방법 (0) | 2023.03.07 |
웹 앱이 Angular(또는 다른 기술)를 사용하여 구축되었는지 어떻게 알 수 있습니까? (0) | 2023.03.07 |
oracle - 커밋해야 할 스테이트먼트는 무엇입니까? (0) | 2023.03.07 |