Coding/React.js

[React] - 11) Hook - useMemo, useCallback

junedev 2019. 12. 6. 15:38
velopert 님의 리액트를 다루는 기술 책으로부터 공부한 내용임을 밝힙니다 😄

Hook

안녕하세요

 

이번엔 지난 포스팅에 이어 함수형 컴포넌트의 Hook에 대해 포스팅합니다.

 

useMemo는 특정 값이 바뀔 때만 호출되어 연산 최적화에 도움을 줍니다.

 

onChange 같은 이벤트 처리 시에 굳이 렌더링 할 필요가 없음에도 불필요하게 렌더링 하는 경우를 최소화 할수 있다는 것입니다.

 

다음 코드를 작성한 후 App에 렌더링 해 봅시다.

import React, { useState, useMemo } 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 = (props) => {
    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;

 

이러면 avg의 값이 변할 때만 useMemo에 의해 렌더링되며, getAverage의 불필요한 호출을 줄일 수 있습니다.

 

useMemo는 렌더링 중 특정 값이 변했을 때만 연산을 실행하고, 그러지 않았다면 이전에 연산했던 결과를 다시 사용하는 방식입니다.

 

useMemo 없이 getAverage를 avg에 그대로 호출한다면 평균값이 변하지 않았을때도 계속해서 호출하게 될 것입니다.

 


 

useMemo가 값이 변환될 때 재사용하게 하려 할때 사용된다면, 특정 경우에만 함수를 재사용 하고 싶은 경우 useCallback을 사용합니다.

 

useCallback는 두 가지 파라미터를 사용하며,

 

useCallback(재사용할 함수(), [값])의 형태로 사용됩니다.

 

배열 형태로 들어간 두 번째 파라미터의 값이 바뀌었을 때 마다, 재사용할 함수를 새로 생성하여 사용하는 방식입니다.

 

useCallback을 사용하면 위 코드를 다음과 같이 변환할 수 있겠네요.

const onChange = useCallback(e => {
        setNumber(e.target.value);
    }, []); // 컴포넌트가 처음 렌더링 됬을 때만 함수 생성

    const onInsert = useCallback(() => {
        const nextList = list.concat(parseInt(number));
        setList(nextList);
        setNumber('');
    }, [number, list]); // num 혹은 list가 바뀌었을 때만 함수 생성

 

 

이상으로 함수형 컴포넌트의 Hook에 대해 어느정도 배워보았습니다.

 

현재 대부분의 클래스형 컴포넌트를 함수형 컴포넌트로 변환하여 사용하도록 권장하는 추세이기 때문에, 라이프사이클링을 대신하는 Hook

 

을 자유자재로 사용하는 것이 중요하다고 합니다. 기존의 setState로 state를 관리하는 것이 나쁜 습관은 아니지만, 그래도 최대한 useState

 

를 활용하여 프로젝트를 진행하도록 하겠습니다.

 

이상으로 포스팅을 마칩니다.