네가 알아야 할 모든 것이 반응할 것이다.의사록(예제 첨부)

아마도 당신은 이미 React에서 일정한 수준에 도달했을 것이다. 당신은 상태와 도구가 무엇인지, 기본적인 React 연결고리인 use State,use Effect를 어떻게 사용하는지 이미 알고 있을 것이다.
아마도, 때때로 React 구성 요소가 느리게 작동하는 것을 알아차리기 시작했을 것이다. (특히 UI 요소와 다른 구성 요소가 많은 중복된 구성 요소)
그것을 어떻게 복원하고 성능을 최적화할 것인가에 대해 생각하기 시작한다...

몇몇 연구를 통해 우연히 React memo라는 것을 발견했다.

너는 자신에게 물어볼 수 있다. 이것은 도대체 무엇입니까?
따라서 React memo는 고급 구성 요소로 React 애플리케이션의 성능을 향상시킬 수 있습니다.
전달된 도구가 변경되지 않으면 렌더링 구성 요소를 건너뜁니다.

그것은 어떻게 일합니까?
아주 간단합니다.비망록은 구성 요소의 렌더링 출력만 기록하고 다음 렌더링 전에 도구를 비교합니다.
변경 사항이 없으면, 비망록은 마지막 렌더링된 출력만 다시 사용합니다.
React에 봉인된 구성 요소 간의 차이를 보여 주는 간단한 예시를 보여 드리겠습니다.이것은 매우 간단한 구성 요소다.
우리는'App'구성 요소가 하나 있는데 상태 변수인'counter'가 있다.
그 밖에 두 개의 하위 구성 요소인 PlainComponent(React.memo-HOC를 사용하지 않는 일반 구성 요소)와 MemoComponent(React.memo-HOC에 포장됨)도 있다.
function App() {
  const [counter, setCounter] = useState(1);
  return (
    <div className="App">
      <p> {counter}</p>
      <button onClick={() => setCounter(counter + 1)}> Set Counter</button>
      <div className="childComponents">
        <MemoComponent />
        <PlainComponent />
      </div>
    </div>
  );
}
const PlainComponent = () => {
  console.info("Child Component - no memo HOC");
  return (
    <div>
      <h3> Plain Component </h3>
    </div>
  );
}
const MemoComponent = React.memo(() => {
  console.info("Child Component - uses memo HOC");
  return (
    <div>
      <h3> Memo Component </h3>
    </div>
  );
}
따라서 카운터를 추가하여 App 구성 요소의 상태를 변경하면 해당 서브어셈블리가 다시 렌더링됩니다.
그러나 보시다시피 일반적인 부분만 다시 과장되었다.


반응을 보이다.비망록과 아이템
그러나 우리는 아직 우리의 서브어셈블리에 어떤 도구도 전달하지 않았다.
만약 우리가 도구를 비망록 부품에 전달한다면 이 도구는 바뀔 것이다.
변경 사항을 무시하거나 어셈블리를 다시 렌더링하고 변경 사항을 반영합니까?
또 다른 예를 봅시다!
우리는 같은'App'과'Memo Component'을 사용할 것이다. 그러나 이번에 나는 App 구성 요소에'passed Prop'상태 변수를 추가했다.
계수기의 나머지 부분이 0이 될 때마다 이 변수는 바뀐다.
저희가 이 아이템을'비망록 모듈'에 전달해야 돼요.
function App() {
  const [counter, setCounter] = useState(1);
  const [passedProp, setPassedProp] = useState(0);

  useEffect(() => {
    if (counter % 5 === 0) setPassedProp(passedProp + 1);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [counter]);

  return (
    <div className="App">
      <p> {counter}</p>
      <button onClick={() => setCounter(counter + 1)}> Set Counter</button>
      <div className="childComponents">
        <MemoComponent prop={passedProp}/>
      </div>
    </div>
  );
}
이 구성 요소에서, 우리는 통과한 도구만 표시할 것이다
const MemoComponent = React.memo(({prop}) => {
  console.info("Child Component - uses memo HOC");
  return (
    <div>
      <h3> Memo Component </h3>
      <p> {prop}</p>
    </div>
  );
}
"passedProp"이 변경될 때마다 메모 구성 요소가 표시됩니다.


반응을 보이다.구성 요소의 의사록 및 상태
용기에 싸인 부품이 반응을 일으키면 어떻게 합니까?memo HOC만의 컨디션이 있는데 이 컨디션이 바뀔까요?
다시 렌더링됩니까?
현재, 우리 Memo 구성 요소에는 'randomNumber' 상태 변수와 수정 단추가 있습니다.
const MemoComponent = React.memo(() => {
  const [randomNumber, setRandomNumber] = useState(Math.random());
  console.info("Child Component - uses memo HOC");

  return (
    <div>
      <h3> Memo Component </h3>
      <p> {randomNumber}</p>
      <button onClick={() => setRandomNumber(Math.random())}>Set random</button>
    </div>
  );
});
"randomNumber"를 변경할 때마다 구성 요소가 다시 렌더링됩니다.

따라서 구성 요소가 실행 중useState,useContext 또는useReducer를 가지고 있으면 상태 (상하문) 가 바뀔 때 다시 나타납니다.

언제 사용합니까?
  • 동일한 아이템의 데이터 재구성 제공
  • UI 요소가 상당수 포함된 대규모 구성 요소

  • 왜 여기저기 안 써요?

    그렇게 지도 모른다, 아마, 아마...
    하지만!!!
    내부 반응.memo는 구성 요소를 다시 렌더링할지 여부를 결정하기 위해 도구 (이전의 상태와 새로운 상태) 를 비교합니다. (도구가 변경되면 다시 렌더링해야 합니다. 그렇지 않으면 안 됩니다.)
    대부분의 경우, 이러한 비교에 사용되는 계산은 더욱 비싸고, 구성 요소를 다시 렌더링하는 것보다 더 많은 시간을 소모할 수 있다

    이것이 바로 네가 React를 사용해서는 안 되는 이유다.만약:
  • 구성 요소 재렌더링 비용 절감
  • 전달된 도구가 자주 변경됨(따라서 메모를 사용하는 것은 의미가 없고 구성 요소는 어쨌든 다시 렌더링됩니다)
  • 비교 함수를 집행하는 비용이 매우 높다
  • Also, you should not use it as a way to "prevent" a render.
    It can lead to bugs!


    마지막으로 내가 언급하고자 하는 것은 사용자 정의 비교 함수인데, 이것은 두 번째 매개 변수로 전달할 수 있다.
    이 함수는 이전 도구와 새 도구를 비교하고 구성 요소를 다시 렌더링해야 하는지 여부를 결정합니다.

    우리 이거 왜 필요해?
    이 예를 고려해 보자.
    App 구성 요소에는 메모 구성 요소에 전달할 1개의 속성으로 구성된 객체가 있습니다.
    우리는 어느 곳에서도 그것을 수정하지 않을 것이다.
    function App() {
      const [counter, setCounter] = useState(1);
      const complexObject = useState({ qty: 0 });
    
      return (
        <div className="App">
          <p> {counter}</p>
          <button onClick={() => setCounter(counter + 1)}> Set Counter</button>
          <div className="childComponents">
            <MemoComponent prop={complexObject} />
          </div>
        </div>
      );
    }
    
    const MemoComponent = React.memo(() => {
      console.info("Child Component - uses memo HOC");
    
      return (
        <div>
          <h3> Memo Component </h3>
        </div>
      );
    });
    
    그러나 우리가'counter'를 점차적으로 늘려서 상태를 바꿀 때마다, 우리의memo 구성 요소는 다시 나타난다. (비록 우리는React.memo를 사용하지만)
    왜 이러지?
    "App"구성 요소의 상태를 바꾸면 대상을 다시 만들고 React는 전달하는 도구가 바뀌었다고 생각해서 구성 요소를 다시 렌더링합니다.


    그렇다면, 어떻게 그것을 복구합니까?
    간단한 완두콩.
    우리는 단지 함수를 두 번째 매개 변수로 전달하여 도구의 두 가지 상태를 비교할 수 있다.
    const MemoComponent = React.memo(
      () => {
        console.info("Child Component - uses memo HOC");
    
        return (
          <div>
            <h3> Memo Component </h3>
          </div>
        );
      },
      (previousProps, nextProps) => {
        return previousProps.prop.qty === nextProps.prop.qty;
      }
    );
    
    따라서 전송 객체의 수량 속성이 변경되었는지 확인합니다.
    도구의 상태가 다르면 false로 돌아가야 합니다. 그러면 구성 요소가 다시 렌더링됩니다.
    그렇지 않으면 함수가true로 되돌아옵니다. 이전에 렌더링한 출력을 사용할 것입니다.

    이렇게, 동료들.
    이제 너는 React를 사용할 수 있다.비망록은 당신의 프로젝트에 있습니다!
    나는 네가 오늘 약간의 새로운 것을 배웠으면 한다.
    만약 당신이 이 댓글을 좋아하거나 아래에 댓글을 남긴다면, 나는 감격해 마지 않을 것입니다.
    그리고 언제든지 저GitHubMedium를 지켜봐 주세요!
    안녕히 계세요

    좋은 웹페이지 즐겨찾기