본문 바로가기
Research/React

useMemo는 불필요한 연산을 줄여준다

by RIEM 2023. 10. 25.

 

import { useState } 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)); // concat rather than push for efficiency
    setList(nextList);
    setNumber('');
  };

  return (
    <div>
      <input value={number} onChange={onChange} />
      <button onClick={onInsert}>Register..</button>
      <ul>
        {list.map((value, index) => (
          <li key={index}>{value}</li>
        ))}
      </ul>
      <div>
        <b>Average: </b>
        {getAverage(list)}
      </div>
    </div>
  );
};

export default Average;

평균을 계산해주는 컴포넌트다.

문제는 인풋에 숫자를 넣을 때마다 렌더링이 된다. 이는 불필요한 리소스를 낭비한다는 의미다.

이 문제는 useMemo라는 훅을 사용하면 해결할 수 있다. useMemo는 함수 컴포넌트 내부에서 진행되는 연산을 최적화해준다고 한다. 

import { useMemo, useState } 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)); // concat rather than push for efficiency
    setList(nextList);
    setNumber('');
  };

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

  return (
    <div>
      <input value={number} onChange={onChange} />
      <button onClick={onInsert}>Register..</button>
      <ul>
        {list.map((value, index) => (
          <li key={index}>{value}</li>
        ))}
      </ul>
      <div>
        <b>Average: </b>
        {avg}
      </div>
    </div>
  );
};

export default Average;

 

댓글