※ 강의를 듣고 제가 이해한 내용을 바탕으로 정리한 것이라서 오류가 있을 수 있습니다.

 

 

useCallback을 사용하여 함수 재사용 하기

함수들은 컴포넌트가 리렌더링 될 때 마다 새로 만들어진다. 함수를 선언하는 것 자체는 사실 메모리도

CPU 도 리소스를 많이 차지 하는 작업은 아니기 때문에 함수를 새로 선언한다고 해서 그 자체 만으로 큰 부하가 생길일은 없지만 한번 만든 함수를 필요할때만 새로 만들고 재사용하는 것은 여전히 중요하다.

 

import React, {useRef, useState, useMemo, useCallback} from 'react';
import UserList from './components/UserList';
import CreateUser from './components/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 = useCallback (e => {
    const {name, value} = e.target;
    setInputs({
      ...inputs,
      [name]: value
    });
  }, [inputs]); // 함수를 이처럼 useCallback() 형태로 감싸준 후 마지막에 deps 배열을 써주어야한다.

  const [users, setUsers] = useState([
    {
        id: 1,
        username: 'progaramexplorer',
        email: 'progaramexplorer@naver.com',
        active: true
    },
    {
        id: 2,
        username: 'tester',
        email: 'tester@gmail.com',
        active: false
    },
    {
       id: 3,
       username: 'liz',
       email: 'liz@daum.net',
       active: false 
    }
]);

const nextId = useRef(4);

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

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

const onToggle = useCallback(id => {
  setUsers(users.map(
    user => user.id === id
    ? {...user, active: !user.active}
    : user
  ));
},[users]);

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

   return (
     <>
        <CreateUser username={username} email={email} onChange={onChange} onCreate={onCreate}/>
        <UserList users={users} onRemove={onRemove} onToggle={onToggle} />
        <div>활성 사용자 수: {count}</div>
     </>
    );
}

export default App;

주의 할 점은 함수 안에서 사용하는 상태 혹은 props 가 있다면 꼭 deps 배열안에 포함시켜야 된다는 것 이다. 만약에 deps 배열 안에 함수에서 사용하는 값을 넣지 않게 된다면 함수 내에서 해당 값들을 참조할때 가장 최신 값을 참조 할 것이라고 보장 할 수 없기 때문이고  props 로 받아온 함수가 있다면 이 또한 deps 에 넣어주어야한다.

+ Recent posts