useCallback

shin·2022년 4월 11일
0

React

목록 보기
13/14
  • 함수의 재사용
  • useCallback을 사용하지 않으면 컴포넌트가 랜더링 될 때마다 함수들이 실행되게 된다.
  • 두번째 파라미터에는 []값이 들어가는데 이 값이 변결 될 때마다 함수가 실행된다.
import React, { useRef, useState, useMemo, useCallback } from 'react';
import UserList from './UserList';
import CreateUser from './CreateUser';


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

function App() {

  const [inputs, setInputs] = useState(
    {
      username: '',
      email: 's'
    }
  );

  const { username, email } = inputs;
  const onChange = useCallback((e) => {
    const {name, value} = e.target;
    setInputs({
        ...inputs,
      [name]: value
    })
  }, [inputs])
  // deps에 inputs를 넣어준다.
  // 그러면 onChage 함수가 바뀔때만 함수가 만들어지고
  // 그렇지 않으면 기존함수를 재사용한다.

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

    const nextId = useRef(4);

    const onCreate = useCallback(() => {
      const user = {
        id: nextId.current,
        username,
        email
      }
      setUsers([...users, user]);
      // setUsers(users.concat(user))
      setInputs({
        username: '',
        email: ''
      })
      console.log(nextId.current);
      nextId.current += 1;
    }, [users, username, email] )
    // username, email 경우 inputs에서 밖으로 빼준 값인데
    // 이런 값들도 결국 상태이기 때문에 넣어줘야 한다
    // 넣지 않으면 함수내부에서 가장 최신상태를 참조하는 것이 아니라
    // 컴퍼넌트가 만들어질 때를 참조하게 된다.

    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(()=>CountAtivedUsers(users),[users]);

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

export default App;

0개의 댓글