[TIL] React.memo 및 useCallback memoization

대빵·2023년 11월 16일
0

내배캠 스탠다드수업에서 유익하고 좋은 내용을 배워서 오늘의 TIL은 스탠다드수업강의를 배운것들을 정리하기로 했닷..!!

1. React.memo로 묶어놨는데도 re-rendering이 되는걸까요?

React.memo가 뭘까요?

React에서 성능 최적화를 위한 고차 컴포넌트로, 이를 사용하면 컴포넌트가 이전에 렌더링된 결과를 기억하고, props가 변경되지 않았을 때 이전 결과를 재사용하여 레더링을 피할 수 있습니다.

일반적으로, React컴포넌트는 부모컴포넌트나 상태가 변경될 때마다 다시 렌더링되지만 React.memo를 사용하면 컴포넌트가 받는 props가 변경되지 않으면 이전에 렌더링한 결과를 캐시하고, 같은 props로 다시 렌더링될 때는 이전 결과를 사용합니다.

💡 리렌더링의 발생 조건

  1. 컴포넌트에서 state가 바뀌었을 때
  2. 컴포넌트가 내려받은 props가 변경되었을 때
  3. 부모 컴포넌트가 리-렌더링 된 경우 자식 컴포넌트는 모두

부모.jsx

export default function 부모 () {
	const [count, setCount] = useState(0);
	
	return (
		<div>
			<button onClick={()=>setCount(count+1)}>플러스</button>
			<자식 />
		</div>
	)
}

자식.jsx

export default function 자식 () {
	
	return (
		<div>헤헤 난 아무것도 안하지롱</div>
	)
}

React.memo React공식문서

예시 React.memo

App.jsx

import React, { useState } from "react";
import Box1 from "./components/Box1";
import Box2 from "./components/Box2";
import Box3 from "./components/Box3";

function App() {
  console.log("App 컴포넌트가 렌더링되었습니다!");

  const [count, setCount] = useState(0);

  // 1을 증가
  const onPlusButtonClickHandler = () => {
    setCount(count + 1);
  };

  // 1을 감소
  const onMinusButtonClickHandler = () => {
    setCount(count - 1);
  };

  return (
    <>
      <h3>카운트 예제입니다!</h3>
      <p>현재 카운트 : {count}</p>
      <button onClick={onPlusButtonClickHandler}>+</button>
      <button onClick={onMinusButtonClickHandler}>-</button>
      <div>
        <Box1 />
        <Box2 />
        <Box3 />
      </div>
    </>
  );
}

export default App;

Box1.jsx

import React from "react";

function Box1() {
  console.log("Box1이 렌더링되었습니다.");
  return <div>Box1</div>;
}

export default Box1;

Box2.jsx

import React from "react";

function Box2() {
  console.log("Box2가 렌더링되었습니다.");
  return <div>Box2</div>;
}

export default Box2;

Box3.jsx

import React from "react";

function Box3() {
  console.log("Box3가 렌더링되었습니다.");
  return <div>Box3</div>;
}

export default Box3;

App컴포넌트에서 button을 클릭을하면 자식컴포넌트인 Box들도 렌더링이 되는것을 볼 수 있습니다. 이런 불 필요한 렌더링을 막기위해서 React.memo를 사용해 불필요한 렌더링을 막아보겠습니다.

Box1.jsx

import React from "react";

function Box1() {
  console.log("Box1이 렌더링되었습니다.");
  return <div>Box1</div>;
}

export default React.memo(Box1);


React.memo를 Box1컴포넌트에만 넣어보았는데 첫 렌더링은 모든 컴포넌트가 렌더링되지만 그 이후 버튼을 클릭할 시 React.memo를 넣어준 자식컴포넌트는 렌더링이 안되는것을 볼 수 있습니다.

예시 useCallback

App.jsx

  // count를 초기화해주는 함수
  const initCount = () => {
    setCount(0);
  };

  return (
    <div style={appStyle}>
      <h3>카운트 예제입니다!</h3>
      <p>현재 카운트 : {count}</p>
      <button onClick={onPlusButtonClickHandler}>+</button>
      <button onClick={onMinusButtonClickHandler}>-</button>
      <div style={boxesStyle}>
        <Box1 />
        <Box2 initCount={initCount} />
        <Box3 />
      </div>
    </div>
  );
}

Box2.jsx

function Box2({ initCount }) {
  console.log("Box2가 렌더링되었습니다.");
  return (
    <div>
      <button onClick={initCount}>초기화</button>
      <div>Box2</div>
    </div>
  );
}

export default React.memo(Box2);


Box2컴포넌트에 React.memo를 사용했지만 리렌더링이 되는게 볼 수 있습니다.

부모컴포넌트가 다시 렌더링하면서 initCount가 새로 생겨서 기존에 있던 initCout함수랑 새롭게 생긴 initCount함수는 다릅니다.

App.jsx

  const initCount = useCallback(() => {
    setCount(0);
  }, []);

initCount는 다시 한번 생성되는게 불필요한데 이러한 불필요한 작업들을 막아주는게 useCallback입니다.

요약

React.memo는 컴포넌트를 memoization을 하고, useCallback은 함수를 memoization을 한다.

0개의 댓글

관련 채용 정보