[간단 일기장] React.memo

미아·2023년 1월 6일
0

REACT

목록 보기
21/41

React.memo

https://ko.reactjs.org/

고차 컴포넌트

  • 기존의 컴포넌트를 새로운 컴포넌트(더 좋아진 컴포넌트)로 반환하는 함수

즉 리액트 메모란

-> 리랜더링하고싶지 않는 함수를 감싸주면, PROPS가 바뀌지않으면 강화된 컴포넌트로 돌려주겠다!
=> 근데 자기자신의 state가 바뀌면 당연히 리랜더링된다!

예시

import React, { useState, useEffect } from "react";
//자식 컴포넌트
const TextView = React.memo(({ text }) => {
  useEffect(() => {
    console.log(`update:: Text :: ${text}`);
  });
  return <div>{text}</div>;
}); // prop 인 text가 바뀌지않으면 랜더링 안됨
const CountView = React.memo(({ count }) => {
  useEffect(() => {
    console.log(`update:: count :: ${count}`);
  });
  return <div>{count}</div>;
});
// 부모 컴포넌트
const OptimizeTest = () => {
  const [count, setCount] = useState(1);
  const [text, setText] = useState("");

  const onChange = (e) => {
    setText(e.target.value);
  };
  return (
    <div style={{ padding: 50 }}>
      <div>
        <h2>count</h2>
        <CountView count={count} />
        {/* count를 prop으로 전달 */}
        <button onClick={() => setCount(count + 1)}>+</button>
      </div>
      <div>
        <TextView text={text} />
        <input value={text} name="input" onChange={onChange}></input>
      </div>
    </div>
  );
};
export default OptimizeTest;

객체를 비교하는 방법


=> 주소값으로 비교하기 때문(얕은 비교)


=> 이렇게 대입한다면 비교가 가능하다

  • areEqual 함수 : props들이 서로 같으면 true 반환, props들이 서로 다르면 false 반환 (areEqual 함수에 의해 판단)
import React, { useState, useEffect } from "react";
// 자식 컴포넌트
const CounterA = React.memo(({ count }) => {
  //useEffect 왜쓰냐면, update될때 다시한번 확인하고, console 찍으려고(두번째 인자 입력안하면 update시 lifecycle 제어)
  useEffect(() => {
    console.log(`counterA update - count: ${count}`);
  });
  return <div>{count}</div>;
  // 버튼 눌러도 콘솔 안찍힘, count값이(prop)이 안변하니까
});
const CounterB = ({ obj }) => {
  useEffect(() => {
    console.log(`counterB update - count: ${obj.count}`);
  });
  return <div>{obj.count}</div>;
};
//버튼 누르면 콘솔찍힘, 왜? 객체이니까 (얕은 비교를 함) , 이용한 메소드 areEqual
const areEqual = (prevProps, nextProps) => {
  //   return true; // 이전 props, 현재 props 같다 -> 리랜더링 일으키지않음
  //   return false; // 이전 props, 현재 props 다르다 -> 리랜더링 일으켜라
  if (prevProps.obj.count === nextProps.obj.count) {
    return true;
  }
  return false;
};

const MemoizedCounterB = React.memo(CounterB, areEqual); // CounterB는 areEqual 함수에 판단에 따라서 할지말지 결정됨
// 부모 컴포넌트
const OptimizeTest = () => {
  const [count, setCount] = useState(1);
  const [obj, setObj] = useState({
    count: 1,
  });
  return (
    <div style={{ padding: 50 }}>
      <div>
        <h2>Counter A</h2>
        <CounterA count={count} />
        <button onClick={() => setCount(count)}>A button</button>
      </div>
      <div>
        <h2>Counter B</h2>
        <MemoizedCounterB obj={obj} />
        <button
          onClick={() =>
            setObj({
              count: obj.count,
            })
          }
        >
          B button
        </button>
      </div>
    </div>
  );
};
export default OptimizeTest;
profile
새로운 것은 언제나 재밌어 🎶

0개의 댓글