React Memoization
Post

React Memoization

Memoization 이란?

이전에 계산한 값을 메모리에 저장함으로써 동일한 계산의 반복 수행을 제거하여 프로그램 실행 속도를 빠르게 하는 기술이다. 적절한 곳에 사용하면 불필요한 렌더링을 줄여 준다. 하지만 Memoization 의 무분별한 사용은 메모리 사용이 많아 지므로 적절한 곳에 사용이 필요하다.

Memoization - Wiki

React 에서 Memoization 사용

React 에서는 Memoization 지원을 위해 아래 3가지 방법을 제공한다.

React.memo

React.memo는 컴포넌트에 사용한다.
React.memo 적용 시 컴포넌트의 props 값이 바뀐 경우에만 해당 컴포넌트가 다시 렌더링 된다. 주로 자식 컴포넌트에 사용된다.

1
2
3
4
5
6
7
// 방법1
const User = React.memo(({user}) => {
  return ()
})

// 방법2
export default React.memo(User);

useMemo

useMemo는 일반 함수에 사용한다.
useMemo를 사용하면 렌더링 과정에서 의존 값이 바뀌었을때만 재실행을 한다.

1
2
3
4
5
const average = useMemo(() => {
    return users.reduce((result, user) => {
      return result + user.score / users.length;
    }, 0);
}, [users])

useCallback

useCallback은 콜백 함수에 사용한다. 콜백 함수는 컴포넌트 내부에 있는 위치해있는 컴포넌트가 렌더링 될 때마다 다시 함수를 생성한다.
하지만 useCallback 을 사용하면 의존 값이 바뀐 경우에만 재생성을 한다.

1
const add = useCallback(() => x + y, [x, y]);

활용 예제

React.memo 를 사용하여 사용유무에 따른 차이점을 비교해보자.

UserList

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import React, { useEffect, useState, useMemo } from 'react';
import { Button } from 'antd';
import User from './User';

const UserList = () => {

console.log("UserList render !");

  const [users, setUsers] = useState([{id: 0, name: "kim", score: 90}, {id: 1, name: "park", score: 70}])

  const addUser = () => {
    console.log('addUser render !')
    setUsers([...users, {id: 2, name: 'Jung', score: 60}]);
  }

  return (
    <>
    <Button onClick={() => {addUser()}}>new user</Button>
    {users.map((user, idx) => {
        return (
            <div key={idx}><User user={user} /></div>
        )
    })}
    </>
  );
};

export default UserList;

User

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import React from 'react';

const User = ({user}) => {

console.log(`User (id: ${user.id}) component render`);

  return (
    <div>
        <div>{user.id} {user.name}</div>
    </div>
  );
};

export default React.memo(User);  // useMemo 적용
// export default User; // useMemo 적용 안한 경우

콘솔 실행 결과

초기화시 id 0,1 번 User가 렌더링 된다.

1
2
3
UserList render !
User.js:5 User (id: 0) component render
User.js:5 User (id: 1) component render

useMemo 를 적용하지 않고 신규 User 추가 시 기존 User가 다시 렌더링 된다.

1
2
3
4
UserList.js:8 UserList render !
User.js:5 User (id: 0) component render
User.js:5 User (id: 1) component render
User.js:5 User (id: 2) component render

useMemo 를 적용하고 신규 User 추가 시 신규 User만 렌더링 된다.

1
2
UserList.js:8 UserList render !
User.js:5 User (id: 2) component render