[React] memo에 대해서 알아보자

김유진·2022년 7월 6일
0

React

목록 보기
11/64
post-custom-banner

1. React.memo에 대해서 알아보자.

컴포넌트는 Props가 변화하거나, setState로 변화하여서 re-render 되는 경우가 있따. 하지만 해당 컴포넌트에서 이러한 일이 일어나지 않고, 상위 컴포넌트에서 이러한 일이 일어난다면 하위 컴포넌트도 자동으로 re-render가 일어나는 경우가 있다.

나는 지금 Re-render가 될 필요가 없는데!!! 진짜 비효율적이야!!!

내 컴포넌트는 memorize 해놓앗다가, 정말 필요한 상황에만 re-render 하게 해주세요!!! 하는 기능이 바로 React.memo 기능입니다!

형식

먼저 import를 해야 합니다.

import React, {useState, useEffect, useCallback} from 'react';

그리고 진짜 코드를 살펴봅시다.

const SubmitComponent = () => (
  <PostSubmitDiv>
    <PostSubmit>작성완료</PostSubmit>
  </PostSubmitDiv>
);

이러한 코드를 다음과 같이 변경해야합니다.

const SubmitComponent = React.memo (() => (
  <PostSubmitDiv>
    <PostSubmit>작성완료</PostSubmit>
  </PostSubmitDiv>
);

아니면 그냥 export 부분을 이렇게 바꾸어도 되죠?

export default React.memo(WriteTitle);

2. useMemo에 대해서 알아보자

import { useState } from 'react';

import React from 'react';

const getAverage = numbers => {
    console.log("평균값 계산 중 ...");
    if (numbers.length === 0 ) return 0;
    const sum = numbers.reduce((a,b) => a + b );
    return sum / numbers.length;
}

const Average = () => {
    const [list, setList] = useState([]);
    const [number, setNumber] = useState('');
    
    const onChange = e => {
        setNumber(e.target.value);
    };
    const onInsert = e => {
        const nextList = list.concat(parseInt(number));
        setList(nextList);
        setNumber('');
    };

    return (
        <div>
            <input value = {number} onChange = {onChange} />
            <button onClick={onInsert}>등록</button>
            <ul>
                {list.map((value, index) => (
                    <li key = {index}>{value}</li>
                ))}
            </ul>
            <div>
                <b>평균값 : </b> {getAverage(list)}
            </div>
        </div>
    )
};
export default Average;

위의 코드는 예제코드이다! 위의 파일은 Average.js인데, 위 파일을 랜더링 하기 위하여 App.js를 만들어준다.

import Average from './Average';

const App = () => {
  return <Average />;
};

export default App;

이렇게 기본적인 세팅을 끝마친다. 먼저 화면이 랜더링될 때 함수가 처음으로 초기화되면서 불려와지니까 console에 log가 하나 찍힌다

원래 console이 찍히는 함수는 함수의 평균값을 구할 때만 찍혀야 되는데 input값을 변경할때마다 계속 계속 찍힌다.

얘 도대체 왜이러는 걸까?

input값이 변경되면서 onChange 함수가 불리게 되고, 그때마다 랜더링이 다시 일어나 모든 함수가 다시 불려와져서 getAverage 함수도 다시 주소를 할당받아 console이 찍히는 것입니다.

아 그러면 인풋 값이 바뀔 때에는 평균값을 다시 계산할 필요가 없네요~
랜더링하는 과정에서 특정 값이 바뀌었을 때에만 연산을 수행하고, 원하는 값이 바뀌지 않았다면 이전에 연산하였던 결과를 다시 사용하는 방식을 고수해야겠습니다.


import React from 'react';

const getAverage = numbers => {
    console.log("평균값 계산 중 ...");
    if (numbers.length === 0 ) return 0;
    const sum = numbers.reduce((a,b) => a + b );
    return sum / numbers.length;
}

const Average = () => {
    const [list, setList] = useState([]);
    const [number, setNumber] = useState('');
    
    const onChange = e => {
        setNumber(e.target.value);
    };
    const onInsert = e => {
        const nextList = list.concat(parseInt(number));
        setList(nextList);
        setNumber('');
    };

    const avg = useMemo(() => getAverage(list), [list]);

    return (
        <div>
            <input value = {number} onChange = {onChange} />
            <button onClick={onInsert}>등록</button>
            <ul>
                {list.map((value, index) => (
                    <li key = {index}>{value}</li>
                ))}
            </ul>
            <div>
                <b>평균값 : </b> {avg}
            </div>
        </div>
    )
};
export default Average;

코드를 이렇게 수정해볼 수 있겠습니다. useMemo를 이용하여서 해당 함수를 감싸고, 두번째 인자값으로는 이 친구가 list가 변경되는지만 확인하기 위하여 list를 넘겨주었네요.
그리고 함수는 어짜피 객체로 취급될 수 있으니까, avg라는 변수에 담아서 그 값을 그대로 출력할 수 있게끔 만들었습니다.

post-custom-banner

0개의 댓글