React : useState에서 객체 배열의 값을 업데이트 할 때 새 객체의 새 배열을 만들자는 이야기
17437 단어 React
요약
제목 긴.
- useState에서 객체의 배열을 관리 할 때 생각했듯이 값을 업데이트 할 수 없어서 빠졌습니다.
- useState로 배열을 갱신할 때는 새로운 배열을 만들어야 한다
- useState로 객체를 업데이트할 때는 새로운 객체의 배열을 만들어야 한다.
- useState에서 객체의 배열을 업데이트 할 때 새 객체의 새 배열을 만들어야합니다.
샘플
이런 TodoList를 만들어 change를 누르면 true/false가 바뀌도록 하고 싶다.
좋은 예 1
change를 눌러도 아무것도 변하지 않는다.
htps : // 코데씨 d보 x. 이오/s/인테페겐 t-조아나우4298?ぃぇ=/src/아 p. js
import { useState } from "react";
export default function App() {
let [items, updateItems] = useState([
{ name: "item 1", done: false },
{ name: "item 2", done: true },
{ name: "item 3", done: false }
]);
return (
<div>
<h2>Todo list</h2>
<ul>
{items.map((item, idx) => {
return (
<li key={idx}>
<span>{`${item.name} ${item.done} `}</span>
<button
onClick={() => {
updateItems((oldItems) => {
oldItems[idx].done = !oldItems[idx].done;
return oldItems;
});
}}
>
change
</button>
</li>
);
})}
</ul>
</div>
);
}
안 좋은 예 2: 새로운 배열을 만들어 보자
과연, 아무래도 새로운 배열을 만들지 않으면 React에 변경이 전해지지 않고 update가 달리지 않는 것 같다.
htps : // m / 10 / 8 / ms / 896df09, d89, 41d48, c
그래서 새로운 배열을 만들어 본다.
h tps : // 코데 씨 d 보 x. 이오/s/아지타테 d-조아나-4kj4s?ぃぇ=/src/아 p. js
<button
onClick={() => {
updateItems((oldItems) => {
oldItems[idx].done = !oldItems[idx].done;
return [...oldItems]; // 新しい配列
});
}}
>
change
</button>
하지만 처음 1회만 바뀌어도 앞으로는 움직이지 않는다...
안 좋은 예 그 3: 새로운 객체를 만들어 보자
객체의 방향을 변경해야 할까 생각 이번에는 배열 내부의 객체를 변경하기로 한다
htps : // 코데씨 d보 x. 이오/s/스에에 t-ゔぃsゔぇsゔ아라야-7yr4s?ぃぇ=/src/아 p. js
<button
onClick={() => {
updateItems((oldItems) => {
// 新しいオブジェクトを作成
oldItems[idx] = {
...oldItems[idx],
done: !oldItems[idx].done
};
return oldItems;
});
}}
>
change
</button>
하지만 움직이지 않는다.
좋은 예 : 새로운 객체를 만들어 새로운 배열에 밀어 넣습니다.
이것으로 생각했던 대로 움직였다.
<button
onClick={() => {
updateItems((oldItems) => {
return oldItems.map((oldItem, oldIdx) => {
if (oldIdx === idx) {
return { ...oldItem, done: !oldItem.done };
}
return oldItem;
});
});
}}
>
change
</button>
왜 잘못 됐는지
React 내부에서는
Object.is
를 사용해 비교하고 있는 것 같다.htps : // 그럼. Rea ctjs. 오 rg / 두 cs / 호오 ks - 레후 렌세. html
htps : //로 ゔぇぺぺr. 모잖아. 오 rg / 쟈 / ㅇ cs / ぇ b / 쟈 ゔ Sc 리 pt / 레후 렌세 / G ぉ 바 l_ 오지 cts / 오 b ct / s # sc p
Object.is의 결과를 표시해 보면 다음과 같이 되었다.
<button
onClick={() => {
updateItems((oldItems) => {
console.log(
"新しい配列の中に古いオブジェクト:",
Object.is(items, [...oldItems]),
Object.is(items[idx], [...oldItems][idx])
); // false, true
oldItems[idx] = {
...oldItems[idx],
done: !oldItems[idx].done
};
console.log(
"古い配列の中に新しいオブジェクト",
Object.is(items, oldItems),
Object.is(items[idx], oldItems[idx])
); // true, true
const newItems = oldItems.map((oldItem, oldIdx) => {
if (oldIdx === idx) {
return { ...oldItem, done: !oldItem.done };
}
return oldItem;
});
console.log(
"新しい配列の中に新しいオブジェクト",
Object.is(items, newItems),
Object.is(items[idx], newItems[idx])
); // false, false
return newItems;
});
}}
>
change
</button>
배열내의 오브젝트를 내부에서 한층 더 어떻게 비교하고 있는지까지는 조사되지 않았지만, 배열 자체도 오브젝트 자체도 Object.is가 false가 되지 않으면 안 되는 것 같다.
이해에 실수, 보다 좋은 쓰는 방법등 있으면 가르쳐 주세요 🙇♂️
Reference
이 문제에 관하여(React : useState에서 객체 배열의 값을 업데이트 할 때 새 객체의 새 배열을 만들자는 이야기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/daitai-daidai/items/5752b308e5e0f9457352텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)