이다닷

[React] Day 19 - useMemo를 사용하여 연산한 값 재사용하기 본문

React

[React] Day 19 - useMemo를 사용하여 연산한 값 재사용하기

이다닷 2023. 9. 23. 18:00

➡️APP 컴포넌트에서 countActiveUsers라는 함수를 만든 후, active 값이 true인 사용자의 수를 세어서 화면에 렌더링하기

 

APP.js 변경

import React, { useRef, useState } from 'react';
import UserList from './qoffhvjxm/UserList';
import CreateUser from './qoffhvjxm/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: 'dndhk',
      email: 'dndhk@gmail.com',
      active: true
    }, {
      id: 2,
      username: 'Lee',
      email: 'Lee@gmail.com',
      active: true
    }, {
      id: 3,
      username: 'dada',
      email: 'dada@gmail.com',
      active: true
    }
  ]);

  const nextId = useRef(4);
  const onCreate = () => {
    const user = {
      id: nextId.current,
      username,
      email
    };
    setUsers([...users, user]);
    setInputs({
      username: '',
      email: ''
    });
    nextId.current += 1;
  };

  const onRemove = ( id ) => {
    setUsers(users.filter(user => user.id !== id));
  };

  const onToggle = id => {
    setUsers(
      users.map(user =>
        user.id === id ? { ...user, active: !user.active } : user
      )
    );
  };
 
  // 함수를 이용한 count 변수 생성
  const count = countActiveUsers(users);
  return (
    <>
      <CreateUser
        username={username}
        email={email}
        onChange={onChange}
        onCreate={onCreate}
      ></CreateUser>
      {/* onToggle 추가 */}
      <UserList users={users} onRemove={onRemove} onToggle={onToggle}></UserList>
      {/* 활성사용자 수를 출력해준다. */}
      <div>활성사용자 수 : {count}</div>
    </>
  );
}

export default App;

 

중간결과사진

 

📢원래는 users에 변화가 있을때만 세어야하지만, input 값이 바뀔때에도 컴포넌트가 계속애서 리렌더링되고있다. 따라서 현재 불필요할때에도 호출되어서 자원이 낭비되고 있다. 이러한 상황에서 useMemo라는 Hook 함수를 사용하면 성능을 최적화할 수 있다.

    ➡️Memo는 "memorized"를 의미하는데, 이는, 이전에 계산한 값을 재사용한다는 의미를 가지고 있다.

 

➡️자원이 낭비되지 않도록 users에 변화가 있을때에만 리렌더링 실행하기

 

APP.js

import React, { useRef, useState, useMemo } from 'react';
import UserList from './qoffhvjxm/UserList';
import CreateUser from './qoffhvjxm/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: 'dndhk',
      email: 'dndhk@gmail.com',
      active: true
    }, {
      id: 2,
      username: 'Lee',
      email: 'Lee@gmail.com',
      active: true
    }, {
      id: 3,
      username: 'dada',
      email: 'dada@gmail.com',
      active: true
    }
  ]);

  const nextId = useRef(4);
  const onCreate = () => {
    const user = {
      id: nextId.current,
      username,
      email
    };
    setUsers([...users, user]);
    setInputs({
      username: '',
      email: ''
    });
    nextId.current += 1;
  };

  const onRemove = ( id ) => {
    setUsers(users.filter(user => user.id !== id));
  };

  const onToggle = id => {
    setUsers(
      users.map(user =>
        user.id === id ? { ...user, active: !user.active } : user
      )
    );
  };
 
  // useMemo를 이용한 count 변수 생성
  const count = useMemo(() => countActiveUsers(users), [users]);
  return (
    <>
      <CreateUser
        username={username}
        email={email}
        onChange={onChange}
        onCreate={onCreate}
      ></CreateUser>
      <UserList users={users} onRemove={onRemove} onToggle={onToggle}></UserList>
      <div>활성사용자 수 : {count}</div>
    </>
  );
}

export default App;

 

결과사진