[TIL] Hooks (3) (useMemo, useCallback)

JunSung Choi·2020년 2월 26일
0

React Hooks

목록 보기
3/4

이번에는 useMemo, useCallback에 대해서 배웠다.

useMemo

useMemo는 "memoized" 를 의미하는데 이는, 이전에 계산 한 값을 재사용한다는 의미를 가지고 있다.
useMemo의 첫번째 파라미터에는 어떻게 연산할지 정의하는 함수를 넣어주면 되고 두번째 파라미터에는 deps 배열을 넣어주면 되는데, 이 배열 안에 넣은 내용이 바뀌면, 우리가 등록한 함수를 호출해서 값을 연산해주고, 만약에 내용이 바뀌지 않았다면 이전에 연산한 값을 재사용하게 된다.

function activeUserCount(users) {
  console.log('활성 사용자 수를 세는중...');
  return users.filter(user => user.active).length;
}
const count = useMemo(() => activeUserCount(users), [users]);

위와 같이 작성할 때 deps로 전달해 준 users의 내용이 바뀔때 등록한 함수가 호출해서 연산된다. 그래서 예를 들어 input 박스의 value가 변경되어 리렌더링 될 때 위 함수는 실행이 안되게 해줄 수 있다. 이로써 어느정도 최적화를 진행한다.

useCallback

useMemo 는 특정 결과값을 재사용 할 때 사용하는 반면, useCallback 은 특정 함수를 새로 만들지 않고 재사용하고 싶을때 사용한다.
컴포넌트 내에서 onChange, onCreate, onRemove 등과 같은 함수를 만들면 이 함수들은 그 컴포넌트가 리렌더링 될 때 다시 새로 만들어진다. 함수를 선언하는 것 자체는 사실 메모리도, CPU 도 리소스를 많이 차지 하는 작업은 아니기 때문에 함수를 새로 선언한다고 해서 그 자체 만으로 큰 부하가 생길일은 없지만, 한번 만든 함수를 필요할때만 새로 만들고 재사용하는 것이 중요하다고 한다.

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

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

위와 같이 작성할 때 useCallback안에서 쓸 함수나 props가 있다면 deps로 전달해줘야 한다.만약에 deps 배열 안에 함수에서 사용하는 값을 넣지 않게 된다면, 함수 내에서 해당 값들을 참조할때 가장 최신 값을 참조 할 것이라고 보장 할 수 없기 때문이라 한다. props 로 받아온 함수가 있다면, 이 또한 deps 에 넣어줘야 한다.

useCallback 최적화

위 예제처럼 작성할 때 dependency에 넣은 배열 데이터가 변결 될 때 재사용되는 것은 맞지만, 안에 users가 변경될 때 함수가 새로 만들어진다.(당연히)

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

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

그래서 위와 같이 setUsers에 함수형 업데이트를 적용하면 users가 최신 값을 얻어올 수 있기 때문에 deps에 users를 지워도 된다.

React.memo

앞에 hooks들은 컴포넌트의 상태, props, 함수의 재사용성을 조작한 것 이라면 React.memo는 리렌더링을 방지하여 컴포넌트의 리렌더링 성능 최적화를 해줄 수 있다.
그러나, 렌더링 최적화 하지 않을 컴포넌트에 React.memo 를 사용하는것은, 불필요한 props 비교만 하는 것이기 때문에 실제로 렌더링을 방지할수있는 상황이 있는 경우에만 사용 하는것을 추천한다.

정리

  1. useMemo 특정 결과값을 상대로 재사용 하고 싶을 때!
    -> 사용 시 첫번째 인자로 사용할 함수, 두번째 인자로 dependency를 전달한다.
  2. useCallback 특정 함수를 새로 만들지 않고 재사용 하고 싶을 때!
    -> useCallback 함수 내에서 쓸 상태나 props, 함수들을 dependency로 전달한다.
  3. React.memeo 컴포넌트의 리렌더링 성능을 최적화 할 때!
profile
Frontend Developer

0개의 댓글