Miracle Morning, LHWN

15. useMemo 를 이용해서 연산된 값을 재사용 본문

IT 기술/[React] 기본

15. useMemo 를 이용해서 연산된 값을 재사용

Lee Hye Won 2021. 5. 25. 13:49
import React, { useRef, useState } from 'react';
import UserList from './UserList';
import CreateUser from './CreateUser';

function countActiveUsers(users) {
  console.log('활성 사용자 수를 세는중...');
  return users.filter(user => user.active).length;
}

function App() {
  const [inputs, setInputs] = useState({
    username: '',
    email: ''
  });
  const { username, email } = inputs;
  const onChange = e => {
    const { name, value } = e.target;
    setInputs({
      ...inputs,
      [name]: value
    });
  };
  const [users, setUsers] = useState([
    {
      id: 1,
      username: 'velopert',
      email: 'public.velopert@gmail.com',
      active: true
    },
    {
      id: 2,
      username: 'tester',
      email: 'tester@example.com',
      active: false
    },
    {
      id: 3,
      username: 'liz',
      email: 'liz@example.com',
      active: false
    }
  ]);

  const nextId = useRef(4);
  const onCreate = () => {
    const user = {
      id: nextId.current,
      username,
      email
    };
    setUsers(users.concat(user));

    setInputs({
      username: '',
      email: ''
    });
    nextId.current += 1;
  };

  const onRemove = id => {
    // user.id 가 파라미터로 일치하지 않는 원소만 추출해서 새로운 배열을 만듬
    // = user.id 가 id 인 것을 제거함
    setUsers(users.filter(user => user.id !== id));
  };
  const onToggle = id => {
    setUsers(
      users.map(user =>
        user.id === id ? { ...user, active: !user.active } : user
      )
    );
  };
  const count = countActiveUsers(users);
  return (
    <>
      <CreateUser
        username={username}
        email={email}
        onChange={onChange}
        onCreate={onCreate}
      />
      <UserList users={users} onRemove={onRemove} onToggle={onToggle} />
      <div>활성사용자 수 : {count}</div>
    </>
  );
}

export default App;

이 소스는 active: tue 인 사용자의 수를 세어서 출력하는 예제이다.

그런데, 여기서 성능적인 문제가 하나 발생하는데 input 의 값을 바꿀 때에도 countActiveUsers 함수가 호출된다는 것이다.

왜 그럴까?

input 의 값이 바뀌는 것은 App 컴포넌트의 state 가 바뀌는 것이고, App 의 state가 바뀌었으니 App 컴포넌트가 리렌더링 되면서

이렇게 불필요할 때에도 호출되는 것이다.

 

useMemo 라는 Hook 함수를 사용해서 성능을 최적화 시켜보기

여기서 Memo 는 memorized를 의미하는데 이전에 계산한 값을 재사용한다는 의미이다.

이전에는 countActiveUsers 의 반환 값을 그대로 변수에 저장했다면, 이번에는 useMemo를 통해 최적화를 시킨다.

const count = useMemo(() => countActiveUsers(users), [users]);

useMemo의 첫 번째 파라미터는 어떻게 연산할지 정의하는 함수를, 두 번째 파라미터는 deps 배열을 넣어주면 된다.

이때 이 deps 배열의 내용이 바뀌면 등록한 함수를 호출해서 연산해주고, 바뀌지 않았으면 이전에 연산한 값을 재사용하는 것이다.


출처 : https://react.vlpt.us/basic/17-useMemo.html

 

17. useMemo 를 사용하여 연산한 값 재사용하기 · GitBook

17. useMemo 를 사용하여 연산한 값 재사용하기 이번에는 성능 최적화를 위하여 연산된 값을 useMemo라는 Hook 을 사용하여 재사용하는 방법을 알아보도록 하겠습니다. App 컴포넌트에서 다음과 같이 co

react.vlpt.us

 

Comments