[React] useMemo, ReactMemo

Jin·2023년 2월 24일
0

React

목록 보기
7/11
post-thumbnail

useMemo?

  • 최적화를 위한 hook이다.

그렇다면 왜 최적화가 필요한 것일까??

reminder : 다음과 같은 경우에 컴포넌트가 re rendering 된다.

  • 자신의 state가 변경되는 경우
  • 부모로부터 받은 props가 변경되는 경우
  • 부모의 state가 변경되는 경우
mport { useState } from 'react';
import './App.css';
import ShowSum from './components/ShowSum';

function App() {
  const [label, setLabel] = useState('Result');
  return (
    <div>
      <ShowSum
        label={label}
        n={10000}
      />

      <button
        onClick={() => setLabel(label + ':')}
      >Change label</button>
    </div>
  );
}

export default App;
import React from 'react';

function sum(n) {
  console.log('Started!!');
  let result = 0;
  for (let i = 1; i <= n; i++) {
    result += i;
  }
  console.log('Finished!!');

  return result;
}

export default function ShowSum({ label, n }) {
  const result = sum(n);
  return (
    <span>
      {label} : {result}
    </span>
  );
}
  • 버튼을 클릭할때마다, sum 함수가 호출이되고, n이 커지게 되면, 렌더링하는데 시간이 오래걸리거나, 문제가 생긴다.
  • 한 번 이미 연산한 부분을 다시 렌더링하기 때문에 성능 낭비이다.
  • 다음와 같은 경우 useMemo를 사용한다.

useMemo 사용하기

  • ShowSum 함수에 useMemo를 추가한다.
import React, { useMemo } from 'react';

function sum(n) {
  console.log('Started!!');
  let result = 0;
  for (let i = 1; i <= n; i++) {
    result += i;
  }
  console.log('Finished!!');

  return result;
}

export default function ShowSum({ label, n }) {
  const result = useMemo(() => {
    return sum(n);
  }, [n]);
  return (
    <span>
      {label} : {result}
    </span>
  );
}
  • useMemo가 값을 기억하고, 다시 연산을 하지 않는다.
  • 이처럼 성능이 오래 걸리는 작업을 할 경우 useMemo를 사용하자

React.memo

  • 앞서 컴포넌트가 re rendering 되는 경우, 세 가지에 대해 언급했었다.
    1. 컴포넌트의 state가 변경되는 경우
    2. 컴포넌트의 props가 변경되는 경우
    3. 부모 컴포넌트의 state가 변경되는 경우

부모 컴포넌트의 state가 변경되는 경우 React.memo를 이용하면 의도치 않은 re rendering을 막을 수 있다.

import { useState } from 'react';
import './App.css';
import Box from './components/Box';

function App() {
  const [count, setCount] = useState(0);
  return (
    <div>
      {/* 부모 컴포넌트의 state가 변할 때, re render가 되는지 확인해보자*/}
      <span>{count}</span>
      <button onClick={() => setCount(prev => prev + 1)}>+</button>
      <Box />
    </div>
  );
}

export default App;
import React from 'react';

export default function Box() {
  console.log('Rendered!');
  const style = {
    width: 100,
    height: 100,
    backgroundColor: 'red',
  }
  return (
    <div style={style}>

    </div>
  );
}
  • 위 코드는 App 컴포넌트의 button을 클릭하면, App 컴포넌트의 state가 변하게 되고, 그 결과 Box 컴포넌트도 re rendering이 되기 때문에 console에 Rendered!가 찍히게 된다.
import React from 'react';

const Box = React.memo(() => {
  console.log('Rendered!');
  const style = {
    width: 100,
    height: 100,
    backgroundColor: 'red',
  }
  return (
    <div style={style}>

    </div>
  );
});

export default Box;
  • 위 처럼 Box 컴포넌트를 React.memo에 감싸주면, 초기 한 번만 render해준다.
profile
Nothing changes if nothing changes

0개의 댓글