TextField 불필요한 다시 렌더링

Nov 06 2020

관련없는 상태 / 소품이 변경되면 동일한 부모 ( 아래 예제의 앱) 내의 모든 구성 요소 가 다시 렌더링되어 페이지 / 양식이 눈에 띄게 느려지는 문제를 발견했습니다.

이벤트 핸들러 및 소품 메모와 같은 많은 조언을 따랐지만 관련없는 구성 요소는 여전히 다시 렌더링됩니다. 난 당황해. 내가 React에 대해 이해하지 못하는 것은 무엇입니까?

[ CodeSandbox ] React 디버거에서 다음을 활성화합니다. 구성 요소가 렌더링 될 때 업데이트 강조 표시

import React, { useMemo, useState } from "react";
import { TextField } from "@material-ui/core";

function MyTextInput(props) {
  return (
    <TextField
      variant={"outlined"}
      onChange={props.onChange}
      value={props.value}
    />
  );
}

export default function App() {
  const [exampleTextValue1, setExampleTextValue1] = useState("");
  const [exampleTextValue2, setExampleTextValue2] = useState("");

  const handleChange1 = useMemo(
    () => (event) => setExampleTextValue1(event.target.value),
    []
  );

  const handleChange2 = useMemo(
    () => (event) => setExampleTextValue2(event.target.value),
    []
  );

  return (
    <>
      <div>
        Change me:
        <MyTextInput value={exampleTextValue1} onChange={handleChange1} />
      </div>

      <div>
        Unrelated inputs. Should not re-render:
        <MyTextInput value={exampleTextValue2} onChange={handleChange2} />
        <MyTextInput value={exampleTextValue2} onChange={handleChange2} />
        {/*  to feel the impact, copy the above line like 98 more times  */}
      </div>
    </>
  );
}

답변

1 Jayce444 Nov 06 2020 at 06:52

디버거 도구는 메모 된 구성 요소와 관련하여 버그가 있습니다. 구성 요소를 메모 할 때 실제로 다시 렌더링되지는 않지만 디버깅 도구가이를 강조 표시합니다 (참조 :https://github.com/facebook/react/issues/19778).

실제로 재 렌더링을 테스트하려면 두 번째 입력 (많이 렌더링 됨)에 대한 기본 상태 값을 "test"와 같은 것으로 변경 한 다음 console.log메모 화 된 MyTextInput구성 요소에 넣어 실제로 다시 렌더링되는 것을 확인합니다.

const MyTextInput = React.memo((props) => {
  console.log(props.value);
  return (
    <TextField
      variant={"outlined"}
      onChange={props.onChange}
      value={props.value}
      disabled={props.disabled}
    />
  );
});

처음 렌더링 할 때 모든 두 번째 입력에 대해 "test"값을 한 번 인쇄 한 다음 첫 번째 입력을 입력 할 때 console.log메모 화 덕분에 모든 두 번째 입력을 기록하지 않는 것을 볼 수 있습니다 .