Skip to content

React:useEffect

Usage

렌더링 될 때 마다 실행

두 번째 인자는 없다.

useEffect(() => {
  // ...
});

첫 렌더링 때 만 실행

두 번째 인자에 빈 배열을 전달.

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

첫 렌더링 때, 그리고 종속성 변수가 바뀌었을 때 실행

두 번째 인자에 종속성 변수를 포함한 배열을 전달.

useEffect(() => {
}, [value1, value2, ...]);

간단히, useEffect 의 콜백 안에서 사용되는 외부 변수 전체를 종속성에 추가하면 된다. (정확힌 로직에 영향을 주는 변수. 보통 영향이 없는 변수는 넣지 않는다)

Clean Up

useEffect()의 함수 안에서 함수를 반환한다.

useEffect(() => {
  return () => {
    // cleanup code ...
  };
}, [value1, value2, ...]);
  • Unmount 될 때 실행.
  • 다음 렌더링 될 useEffect() 실행 직전에 실행.

Sample example

로딩, 데이터, 에러 케이스가 필요하다.

import React, { useState, useEffect } from "react";

function Profile({ userId }) {
  const [loading, setLoading] = useState(true);
  const [user, setUser] = useState(null);
  const [error, setError] = useState(null);

  useEffect(() => {
    window
      .fetch(`https://jsonplaceholder.typicode.com/users/${userId}`)
      .then((res) => res.json())
      .then((user) => {
        setUser(user);
        setLoading(false);
      })
      .catch((error) => {
        setError(error);
        setLoading(false);
      });
  }, [userId]);

  if (loading) return <p>Loading...</p>;
  if (error) return <p>Error!</p>;

  return (
    <ul>
      <li>id: {user.id}</li>
      <li>email: {user.email}</li>
      <li>name: {user.name}</li>
      <li>phone: {user.phone}</li>
      <li>website: {user.website}</li>
    </ul>
  );
}

Async ver

useEffect(async () => {...});와 같이 직접 호출하면 Promise 객체가 반환되므로 하면 안된다. 대신 콜백 안에서 호출하자:

useEffect(() => {
  (async () => {
    // TODO ...
  })();
}, [param])

Fetch 를 Abort 가능하도록

useEffect(() => {
  const controller = new AbortController();
  const signal = controller.signal;

  fetch(`/api/users/${id}`, {signal})
    .then(res => res.json())
    .then(data => {
      setUser(data);
    });

  return () => {
    controller.abort();
  };
}, [id])

See also

Favorite site