본문 바로가기
SPA/React

[React] React.memo로 최적화하기

by J4J 2021. 9. 30.
300x250
반응형

안녕하세요. J4J입니다.

 

이번 포스팅은 React.memo로 최적화하는 방법에 대해 적어보는 시간을 가져보려고 합니다.

 

 

 

React.memo란?

 

React.memo는 함수형 컴포넌트에서 동일한 파라미터로 생성된 함수들을 메모이제이션을 이용하여 재사용하게 도와줍니다.

 

 

 

예를 들어 다음과 같은 상황이 있다고 가정해보겠습니다.

 

이름, 나이, 주소값을 useState를 이용하여 표현하고 있고 주소를 제외한 이름, 나이를 파라미터로 받는 컴포넌트가 있습니다.

 

여기서 이름, 나이 값이 변경되면 해당 값을 가져다 사용하는 컴포넌트도 당연히 리 렌더링이 발생되어 수정된 화면을 보여줘야 됩니다.

 

하지만 주소값이 변경될 경우는 어떨까요?

 

주소 값이 변경되더라도 useState로 정의된 값들은 같이 리 렌더링이 발생되기 때문에 이름, 나이 값이 동일함에도 불구하고 해당 값들을 가져다 사용하는 컴포넌트도 리 렌더링이 발생됩니다.

 

결국 굳이 리렌더링하지 않아도 되는 상황에서 리 렌더링을 함으로써 추가적인 작업을 해주게 됩니다.

 

 

반응형

 

 

이런 상황에서 React.memo를 이용해줄 수 있습니다.

 

React.memo를 사용하면 컴포넌트에서 전달받는 파라미터 값을 확인하고 파라미터 값이 동일할 경우에는 리 렌더링을 발생시키지 않게 됩니다.

 

결과적으로 주소값이 변경되더라도 해당 컴포넌트는 리 렌더링이 발생되지 않고 단순하게 저장해둔 값을 가져다 사용함으로써 서비스 속도를 향상시켜줍니다.

 

 

 

하지만 React.memo에도 당연히 단점이 존재합니다.

 

메모이제이션 처리를 위한 작업 시간이 필요하기 때문에 만약 동일한 파라미터 값이 들어가는 경우가 드문 경우, 즉 메모이제이션 처리가 이루어진 컴포넌트가 이후에 자주 사용되지 않는 환경에서는 오히려 악영향을 미칠 수 있습니다.

 

무분별한 사용은 오히려 서비스 속도를 낮추는 결과를 초래하기 때문에 동일 파라미터가 자주 사용되는지를 잘 판단하고 사용해주셔야 됩니다.

 

 

 

React.memo 사용 방법은 정말 간단합니다.

 

우선 'react'패키지에서 제공해주는 기능이기 때문에 리액트로 개발되는 곳 어디에서든 사용할 수 있습니다.

 

또한 사용할 때는 단순하게 컴포넌트를 export 해줄 때 React.memo를 이용하여 컴포넌트를 덮어주기만 하면 됩니다.

 

간단한 예시 코드를 보여드리겠습니다.

 

 

 

예시 코드

 

코드 실행은 위에서 언급한 예시와 동일한 결과가 나오게 해 보겠습니다.

 

 

 

가장 먼저 App.jsx입니다.

 

다음과 같이 작성해보겠습니다.

 

import * as React from 'react';
import MyComponent, { MemoizedMyComponent } from './myComponent';

const App = () => {
    const [name, setName] = React.useState('');
    const [age, setAge] = React.useState('');
    const [address, setAddress] = React.useState('');

    return (
        <div>
            <table>
                <tbody>
                    <tr>
                        <td>
                            <span>이름</span>
                        </td>
                        <td>
                            <input type="text" value={name} onChange={(e) => setName(e.target.value)}/>
                        </td>
                    </tr>
                    <tr>
                        <td>
                            <span>나이</span>
                        </td>
                        <td>
                            <input type="number" value={age} onChange={(e) => setAge(e.target.value ? Number(e.target.value) : undefined)} />
                        </td>
                    </tr>
                    <tr>
                        <td>
                            <span>주소</span>
                        </td>
                        <td>
                            <input type="text" value={address} onChange={(e) => setAddress(e.target.value)}/>
                        </td>
                    </tr>
                </tbody>
            </table>

            <MyComponent name={name} age={age} /> {/* 메모이제이션 적용되지 않은 컴포넌트 */}
            <MemoizedMyComponent name={name} age={age} /> {/* 메모이제이션 적용된 컴포넌트 */}
        </div>
    )
}

export default App;

 

 

728x90

 

 

그리고 App.jsx와 동일 위치에 myComponent.jsx를 생성하여 다음과 같이 작성해보겠습니다.

 

import * as React from 'react';

const MyComponent = ({ name, age }) => {

    React.useEffect(() => {
        console.log(`name: ${name}, age: ${age}`); // 리렌더링 될 때마다 출력
    });

    return (
        <div style={{borderTop: '2px solid orange', borderBottom: '2px solid orange', margin: '6px 0'}}>
            <h2>name: {name}</h2>
            <h4>age: {age}</h4>
        </div>
    )
}

export default MyComponent; // 메모이제이션 적용 X

export const MemoizedMyComponent = React.memo(MyComponent); // 메모이제이션 적용 O

 

 

 

코드를 작성하고 실행해보면 다음과 같습니다.

 

실행 결과

 

 

 

간단히 설명드리면 다음과 같습니다.

 

  • 이름을 입력할 경우 → 파라미터로 전달되는 값이어서 모든 컴포넌트가 리 렌더링 되어 콘솔 출력 (2개씩 출력)
  • 나이를 입력할 경우 → 이름과 동일
  • 주소를 입력할 경우 → 파라미터로 전달되는 값이 아니어서 메모이제이션이 적용되지 않은 컴포넌트만 콘솔 출력 (1개씩 출력)

 

 

 

 

 

이상으로 React.memo로 최적화하는 방법에 대해 간단하게 알아보는 시간이었습니다.

 

읽어주셔서 감사합니다.

 

 

 

728x90
반응형

'SPA > React' 카테고리의 다른 글

[React] CRA로 만들지 않았을 때 dotenv 사용 방법 (index.html 포함)  (0) 2021.11.16
[React] recoil 사용하기  (0) 2021.10.24
[React] Hooks - useReducer  (0) 2021.09.27
[React] Hooks - useMemo  (0) 2021.09.22
[React] Hooks - useCallback  (0) 2021.09.15

댓글