티스토리 뷰

자식 컴포넌트의 재렌더링을 막아보자..!

 

memo()

  • 꼭 필요할 때만 재렌더링해줌
  • memo()로 재렌더링이 오래걸리는 컴포넌트를 감싸두면 성능개선에 도움이 됨

📘 memo() 사용해서 Cart() 재렌더링 시 같이 재렌더링되는 Child 컴포넌트 막기

import { memo } from 'react';

// function Child(){
//   console.log('재렌더링됨')
//   return <div>자식 컴포넌트!</div>
// }

let Child = memo(function(){
  console.log('재렌더링됨')
  return <div>자식 컴포넌트!</div>
})

function Cart(){

  return (
    <div>
      <Child></Child>
      <button onClick={() => { setCount(count+1) }}>+</button> {/* Cart() 재렌더링 시 자식 컴포넌트인 Child()도 재렌더링 */}
    ...

 

 

memo()의 원리

  • props가 변할 때만 재렌더링을 해줌
import { memo, useState } from 'react';

let Child = memo(function(){
  console.log('재렌더링됨')
  return <div>자식 컴포넌트!</div>
})

function Cart(){
  let [count, setCount] = useState(0)
  return (
    <div>
      <Child count={count}></Child>
      <button onClick={() => { setCount(count+1) }}>+</button>
    ...

-> 버튼을 클릭 할 때마다 props가 변하면서 Cart() 컴포넌트가 재렌더링 됨

버튼 클릭시 콘솔창

 

❗ memo()는 기존 props == 신규 props를 계속 비교함

-> props가 길고 복잡하면 memo() 사용이 오히려 손해일 수도 있음

 

 


useMemo()

  • 사용시 컴포넌트 렌더링시 1회만 실행해줌
  • useEffect와 유사
  • useEffect의 의존성 배열에 name이란 state를 넣었을 때 -> age state를 변경해도 useEffect가 실행됨.
    이유: 자바스크립트에서 객체는 값이 저장될 때 주소 값으로 저장(참조타입)되기 때문이다. <-> 원시타입(객체값)
    그래서: age state가 변경되면 App 컴포넌트 재호출 -> name의 주소값 변경 -> name이 변경된걸로 인식 -> useEffect 실행
    => 이걸 useMemo()로 방지
import { useMemo } from 'react';

/* useMemo */
function 함수(){
  return 반복문을10억번돌린결과
}

function Cart(){
  let result = 함수();
  useMemo(() => { return 함수() }, [state]) // useMemo 사용시 [state]가 변할 때마다 컴포넌트 렌더링시 1회만 실행해줌
  ...

 

 

useMemo / useEffect 비교

  • useMemo: HTML 렌더링될 때 같이 실행
  • useEffect : HTML 다 실행된 후 실행
 

 

댓글