React

react - key!!!

jyeounjae 2022. 11. 26. 17:41

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を使ってランダムでコンポーネントを出力。

 

first
second

最初は下のキーが4のボタンにフォーカシングだったが、

{ id: 4, value: "learning" }

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を付与した。

 

first
second

キーを付与すると、最初フォーカスされたキーが、再度レンダーリングされても、

正しいボタンにフォーカスされていることがわかる。


리액트에서 키가 중요한 이유는 "리랜더링" "재사용" 을 하기 위해서이다

랜덤한 상태에서, 탭을 하면 버튼이 포커싱됨.

키를 지정하지 않은 상태에서, 만약 세번째 버튼에 포커싱이 된 경우, 랜덤하게 컴포넌트가 움지이는데(실제는 아님)

이 상황에서 포커싱은 계속 세번째에만 포커싱이 되어 있음(실제론 컴포넌트는 그대로 위치해있고 값만 바뀜)

이러한 것은 결국 버튼은 계속 그대로인데 값만 바꿔치기 하고 있다는 것을 알 수 있다

(컴포넌트가 재사용되는)

 

결국, 리액트에서의 리랜더링은 

키를 제대로 주지 않으면 제대로 사용되기 어렵다

 

indexも可能が、、

 

https://ko.reactjs.org/docs/reconciliation.html

 

재조정 (Reconciliation) – React

A JavaScript library for building user interfaces

ko.reactjs.org