[React] useMemo, useCallback 복습

jiseong·2022년 1월 1일
0

T I Learned

목록 보기
158/291

useMemo

예전에 달력을 직접 만들어보면서 달력의 상위 컴포넌트 중에 input의 값이 변경될 때마다 하위 컴포넌트인 달력 컴포넌트가 계속된 불필요한 계산으로 느려진 현상이 있었다.

이를 해결하기 위해 useMemo를 사용하여 달력의 좌우버튼을 클릭하여 달이 바뀔 때에만 새롭게 계산될 수 있도록 구현함으로써 해결할 수 있었다.

  • useMemo를 사용하면 State나 Props가 변경될경우 해당값을 활용해 계산된값을 메모이제이션하여 재렌더링시 불필요한 연산을 줄일 때 사용하는 Hook이다.

복습

import ReactDOM from 'react-dom';
import React, { useState, useMemo } from 'react'

const NameLength = () => {
  const [nickname, setNickname] = useState('')
  const nicknameLength = useMemo(() => nickname.length, [nickname]);

  const updateNickname = event => {
    const nickname = event.target.value
    
    setNickname(nickname)
  }

  return (
    <div>
      <input onChange={updateNickname} />
      <br/>
      <label>{nicknameLength}</label>
    </div>
  )
}

ReactDOM.render(<NameLength />, document.getElementById('root'));

nickname이라 변수를 의존성으로 전달하여 nickname이 변경되었을 때만 값을 다시 계산하도록 코드를 작성하였다.

useCallback

useCallback의 경우에도 상위 컴포넌트에서 하위 컴포넌트로 함수를 전달하는 과정에서 함수를 새롭게 생성해서 보내주어 불필요한 리렌더링을 하고 있어서 이를 해결하려고 사용했던 적이 있었다.

  • useCallback은 함수를 메모이제이션하기 위해 사용하는 Hook으로 컴포넌트가 재렌더링될 때 불필요하게 함수가 다시 생성되는 것을 방지한다.

복습

import ReactDOM from 'react-dom';
import React, { useCallback, useState, useMemo } from 'react'

const SumString = () => {
  const [string, setString] = useState('');
  const [stringList, setStringList] = useState([]);

  const change = useCallback((e) => {
    setString(e.target.value);
  }, []);
  
  const insert = useCallback(() => {
    const newList = stringList.slice();
    newList.push(string);
    setStringList(newList);
  }, [string, stringList]);
  
  const sum = useCallback((list) => {
    let stringSum = '';

    for(let i = 0; i < list.length; i++){
      stringSum += list[i] + ' ';
    }
    
    return stringSum;
  }, []);

  const result = useMemo(() => sum(stringList), [stringList, sum]);

  return (
    <div>
      <input type='text' onChange={change}/>
      <button onClick={insert}>문자열 붙이기</button>
      <br/>
      {result}
    </div>
  )
}

ReactDOM.render(<SumString />, document.getElementById('root'));

위의 코드에서 sum의 함수의 경우 useCallback을 사용하지 함수일 경우 input값에 value가 변경될때마다 해당 컴포넌트가 다시 렌더링하기 때문에 적힌 수만큼 sum 함수가 호출되는 것을 볼 수 있다.

const sum = (list) => {
  console.log('NoneUseCallback innerSum');
  let stringSum = '';

  for(let i = 0; i < list.length; i++){
    stringSum += list[i] + ' ';
  }

  return stringSum;
}

하지만 useCallback을 사용한다면 처음 렌더링 했을 때만 호출되는 것을 확인 할 수 있다.

const sum = useCallback((list) => {
  console.log('innerSum');
  let stringSum = '';

  for(let i = 0; i < list.length; i++){
    stringSum += list[i] + ' ';
  }

  return stringSum;
}, []);


Reference

0개의 댓글