react - key!!!
Reactでキーが重要な理由としては"re-rendering"をするため!
以下は、コンポーネントがランダムに出力される例です。
以下では、キーを指定した時のコンポーネント配置としない時のコンポーネントの
違いがわかります。
<!DOCTYPE html>
<html lang="en">
<body>
<div id="root"></div>
<script src="https://unpkg.com/react@16.12.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.12.0/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone@7.8.3/babel.js"></script>
<script type="text/babel">
const rootElement = document.getElementById("root");
const todos = [
[
{ id: 1, value: "wash dishes" },
{ id: 2, value: "clean the bed" },
{ id: 3, value: "running" },
{ id: 4, value: "learning" }
],
[
{ id: 4, value: "learning" },
{ id: 1, value: "wash dishes" },
{ id: 2, value: "clean the bed" },
{ id: 3, value: "running" }
],
[
{ id: 3, value: "running" },
{ id: 1, value: "wash dishes" },
{ id: 2, value: "clean the bed" },
{ id: 4, value: "learning" }
],
[
{ id: 2, value: "clean the bed" },
{ id: 3, value: "running" },
{ id: 1, value: "wash dishes" },
{ id: 4, value: "learning" }
]
];
const App = () => {
const [items, setItems] = React.useState(todos[0]);
React.useEffect(() => {
const interval = setInterval(() => {
const random = Math.floor(Math.random() * 3);
setItems(todos[random]);
}, 1000);
return () => {
clearInterval(interval);
};
}, []);
const handleDoneClick = (todo) => {
setItems((items) => items.filter((item) => item !== todo)); // todo로 넘어온 값이랑 같지 않으면 지우지 않는다
};
const handleRestoreClick = (todo) => {
setItems((items) => [
...items,
todos.find((item) => !items.includes(item))
]);
};
return (
<>
{items.map((todo) => (
<div key={todo.id}>
<button onClick={() => handleDoneClick(todo)}>
{todo.value}
</button>
</div>
))}
<br />
<br />
<button onClick={handleRestoreClick}>Restore</button>
</>
);
};
ReactDOM.render(<App />, rootElement);
</script>
</body>
</html>
const [items, setItems] = React.useState(todos[0]);
React.useEffect(() => {
const interval = setInterval(() => {
const random = Math.floor(Math.random() * 3);
setItems(todos[random]);
}, 1000);
return () => {
clearInterval(interval);
};
}, []);
useEffectを使ってランダムでコンポーネントを出力。
最初は下のキーが4のボタンにフォーカシングだったが、
2番目の写真では、runningにフォーカスされていることがわかる。
<>
{items.map((todo) => (
<div key={todo.id}>
<button onClick={() => handleDoneClick(todo)}>
{todo.value}
</button>
</div>
))}
<br />
<br />
<button onClick={handleRestoreClick}>Restore</button>
</>
うえは,buttonのdivにkeyを付与した。
キーを付与すると、最初フォーカスされたキーが、再度レンダーリングされても、
正しいボタンにフォーカスされていることがわかる。
리액트에서 키가 중요한 이유는 "리랜더링" "재사용" 을 하기 위해서이다
랜덤한 상태에서, 탭을 하면 버튼이 포커싱됨.
키를 지정하지 않은 상태에서, 만약 세번째 버튼에 포커싱이 된 경우, 랜덤하게 컴포넌트가 움지이는데(실제는 아님)
이 상황에서 포커싱은 계속 세번째에만 포커싱이 되어 있음(실제론 컴포넌트는 그대로 위치해있고 값만 바뀜)
이러한 것은 결국 버튼은 계속 그대로인데 값만 바꿔치기 하고 있다는 것을 알 수 있다
(컴포넌트가 재사용되는)
결국, 리액트에서의 리랜더링은
키를 제대로 주지 않으면 제대로 사용되기 어렵다
indexも可能が、、
https://ko.reactjs.org/docs/reconciliation.html
재조정 (Reconciliation) – React
A JavaScript library for building user interfaces
ko.reactjs.org