[React] The Effect Hook

윤남주·2022년 1월 20일
0

리액트 부수기

목록 보기
13/21
post-thumbnail

해당 포스트는 코드아카데미의 React 101 강의의 필기입니다.


useEffect

첫 렌더링 이후에도 어떤 동작을 실행시키기 위해 사용하는 훅. Mounting, Updating, Unmounting phase에 필요한 side effect를 실행시킬 수 있다.

Effect Hook의 예시

import React, { useState, useEffect } from 'react';
 
function PageTitle() {
  const [name, setName] = useState('');
 
  useEffect(() => {
    document.title = `Hi, ${name}`;
  });
 
  return (
    <div>
      <p>Use the input field below to rename this page!</p>
      <input onChange={({target}) => setName(target.value)} value={name} type='text' />
    </div>
  );
}
  1. useState 훅과 마찬가지로 useEffect 훅을 import 해야함
  2. useEffect의 첫번째 인자는 실행시킬 콜백 함수 = effect
  3. 첫 렌더링 시 DOM을 렌더링하고, 그 이후에 effect를 실행시킨다 (일단 처음은 무조건 실행)
  4. 이후 재렌더링시 계속 실행시킨다 (두번째 인자값에 따라 다름)



Clean Up Function

사용이 끝난 코드들은 제거를 해주어야 memory leak를 방지할 수 있다.

useEffect(()=>{
  document.addEventListener('keydown', handleKeyPress);

  return () => {
    document.removeEventListener('keydown', handleKeyPress);
  };
})

return 뒤의 함수(cleanup function)가 없었다면 쓸데없이 이벤트 리스너가 계속 실행됨. 심지어 버그, 충돌까지 일으킬 수 있음.
(위와 같은 경우, 이벤트 리스너 제거를 해주지 않으면 같은 이벤트 리스너가 계속 쌓임)

  1. 첫 렌더링 시 이펙트 실행
  2. 재렌더링 시 클린업 함수 실행 → 이펙트 실행
  3. Unmount 되면 클린업 함수 실행 후 끝남

Clean up 함수를 만드는 것은 개발자의 재량이므로 Memory leak를 최소화할 수 있는 방법을 항상 생각해야한다.


Control when Effects are Called

재렌더링 될 때마다 실행하고 싶진 않은 경우 → dependency array 를 사용한다

useEffect(()=>{}, [])

  • 첫번째 인자 : effect + clean up function
  • 두번째 인자 : dependency array

➡️ 첫 렌더링 때는 항상 실행되지만, 이후에는 dependency array에 있는 항목이 변화될 때만 렌더링 된다.

✨ 만약 빈 배열[]을 dependency array로 준 경우, 첫 렌더링에만 실행되고 그 이후로는 실행되지 않는다

🔥 setInterval 코드 예시

  useEffect(() => {
    const intervalId = setInterval(() => {
      setTime((prev) => prev + 1)
    }, 1000);

    return () => {clearInterval(intervalId)}
  }, [])

Fetch

서버에서 데이터를 가져오는 경우 특히 effect 발생 시점을 잘 관리해야함

  • 처리 속도
  • 성능
  • 모바일 유저의 데이터 소모
  • API 서비스 요금

등을 고려해야하기 때문.

💡 useState와 useEffect를 함께 사용하여 첫 렌더링 후 모든 데이터를 받아와 state에 저장하는 방법으로 한번만 통신해도 되도록 만들 수 있음.




Rules of Hooks

  • only call Hooks at the top level
  • only call Hooks from React functions

리액트는 컴포넌트에 대한 정보 (jsx, 함수 등)을 계속 refresh 하는데, 이 때 배치 순서가 중요함. Hooks는 그래서 절대 반복문, 조건문, 혹은 하위 요소로 선언하지 않음!

나쁜 예)

if (userName !== '') {
  useEffect(() => {
    localStorage.setItem('savedUserName', userName);
  });
}

좋은 예)

useEffect(() => {
  if (userName !== '') {
    localStorage.setItem('savedUserName', userName);
  }
});

그리고 클래스형 컴포넌트에서 혹은 바닐라 JS에선 Hooks를 절대 사용할 수 없다!

profile
Dig a little deeper

0개의 댓글