반응: Key Prop 이해하기
React
개발자의 질문 중 하나에 대한 일종의 고전적인 질문입니다. 맞습니까?관련 게시물을 읽고 있었는데 갑자기
key
소품에 대한 다음과 같은 질문을 받았습니다.React
는 메모리에 RealDOM과 비교하기 위한 virtualDOM이 있으며 필요한 부분을 업데이트합니다.이것이
React
가 렌더링에 작동하는 방식에 대해 내가 아는 전부입니다. 더 많은 정보를 검색하여 Reconciliation
설명서에서 React
에 대해 읽었습니다.Reconciliation은 DOM 업데이트를 위해 React가 작동하는 프로세스입니다.
문서에서
If we used this in React, displaying 1000 elements would require in the order of one billion comparisons. This is far too expensive. Instead, React implements a heuristic O(n) algorithm based on two assumptions:
Two elements of different types will produce different trees.
The developer can hint at which child elements may be stable across different renders with a key prop.
키가 같으면 뭔가 잘못될 수 있기 때문에 인덱스를
key
소품으로 사용하면 안 된다는 것을 알고 있었습니다.하지만 어떤 것도 테스트해 본 적이 없었기 때문에 거기에서 어떤 일이 일어날지 확신할 수 없었기 때문에 오늘
key
소품에 대해 파헤치기로 했습니다.키는 React가 변경된 요소를 식별하는 데 도움이 됩니다.
import { useState } from 'react';
function ExampleA() {
const [value, setValue] = useState(false);
const toggle = () => setValue(!value);
return (
<div>
{value ? (
<div
style={{ color: 'red' }}
onClick={() => {
alert('hello');
}}
>
Hello
</div>
) : (
<div>Bye</div>
)}
<button onClick={toggle}>Toggle</button>
</div>
);
}
export default ExampleA;
누군가는 값에 따라 다른 div 요소를 렌더링한다고 생각할 수 있습니다. (RealDOM에서)
동일한 div 태그입니다. 속성을 변경하는 것이 좋습니다. 요소가 아닙니다.
요소를 변수에 저장했습니다. 토글 버튼을 누른 다음 변수를 확인했습니다.
그들은 동일합니다.
하지만 키가 다르다면?
import { useState } from 'react';
function ExampleA() {
const [value, setValue] = useState(1);
const toggle = () => setValue(value > 0 ? 0 : 1);
return (
<div>
{value ? <div key={value}>Hello</div> : <div key={value}>Bye</div>}
<button onClick={toggle}>Toggle</button>
</div>
);
}
export default ExampleA;
코드는 다음과 같습니다.
RealDOM에 있던 요소가 제거되고 새 요소가 생성됩니다.
인덱스를 키로 사용하여 .map을 사용하여 배열 렌더링
import { useEffect, useState, useMemo } from 'react';
function Time({ time }: { time: string }) {
useEffect(() => {
console.log({ time });
}, [time]);
return <div>{time}</div>;
}
function ExampleB() {
const [times, setTimes] = useState<string[]>([]);
const addItem = () => {
setTimes([new Date().toString(), ...times]);
};
const elements = useMemo(() => {
return times.map((time, timeIdx) => <Time key={timeIdx} time={time} />);
}, [times]);
return (
<div>
<button type="button" onClick={addItem}>
Add Item
</button>
<hr />
{elements}
</div>
);
}
export default ExampleB;
항목을 추가하면 어떻게 되는지 살펴보겠습니다.
항목을 추가할 때마다 모든 항목이 업데이트됩니다.
const elements = useMemo(() => {
return times.map((time) => <Time key={time} time={time} />);
}, [times]);
키를
time
로 변경했습니다. 그리고 다시 보자.이제 잘 작동하는데 왜 제대로 작동하지 않습니까?
이 사진들을 보세요.
키로 인덱스
time
를 key
로key
는 요소를 구별하는 데 사용됩니다. 이상이 없어 보여도 관리를 해야 합니다.다른 예를 보자.
import { useState, useMemo } from 'react';
function ExampleC() {
const [times, setTimes] = useState<string[]>([]);
const addItem = () => {
setTimes([new Date().toString(), ...times]);
};
const elements = useMemo(() => {
const handleDelete = (timeIdx: number) => () => {
setTimes((prevTimes) => prevTimes.filter((_, idx) => idx !== timeIdx));
};
return times.map((time, timeIdx) => (
<div key={timeIdx}>
<div>time: {time}</div>
<div>
<label>memo</label>
<input type="text" />
</div>
<button type="button" onClick={handleDelete(timeIdx)}>
Delete
</button>
<hr />
</div>
));
}, [times]);
return (
<div>
<button type="button" onClick={addItem}>
Add Item
</button>
<hr />
{elements}
</div>
);
}
export default ExampleC;
항목이 3개 있는데 두 번째 항목을 삭제하겠습니다.
두 번째
input
의 텍스트는 'CCCC'가 아니라 'BBBB'입니다.왜요?
React
는 key 3
가 제거된 것으로 인식하므로 'CCCC'가 있는 입력란은 key 3
의 자식이므로 삭제되며, 예, key 2
의 시간은 '00:02'에서 변경됩니다. ' -> '00:01'.결론
나는 편집이나 삭제 기능이 없을 때 index
를 key
소품으로 자주 사용했습니다. 잘 작동하는 것 같았기 때문입니다.
지금은 그렇지 않았을 수도 있다는 것을 알게 되었고 key
소품을 좀 더 신중하게 다루도록 하겠습니다.
나는 이것이 누군가에게 도움이되기를 바랍니다 :)
행복한 코딩!
Reference
이 문제에 관하여(반응: Key Prop 이해하기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://dev.to/lico/about-key-prop-in-react-2mno
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Reference
이 문제에 관하여(반응: Key Prop 이해하기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/lico/about-key-prop-in-react-2mno텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)