deep-dive-everything / typescript-with-react

우아한 타입스크립트 with 리액트 스터디
0 stars 0 forks source link

useEffect 내에 비동기 함수가 들어갈 수 없는 이유가 무엇일까요? #39

Open kwonhygge opened 1 week ago

kwonhygge commented 1 week ago

📚 290p 📌 useEffect 내에 비동기 함수가 들어갈 수 없는 이유가 무엇일까요?

hotdog1004 commented 1 day ago

useEffect의 타입 정의(@types/react v18 기준)

  type DependencyList = readonly unknown[];
  type EffectCallback = () => void | Destructor;
  function useEffect(effect: EffectCallback, deps?: DependencyList): void;

useEffect의 첫번째 인자인 effect의 타입인 EffectCallback은 Destructor를 반환하거나 아무것도 반환하지 않는 함수입니다. 여기에 Promise 타입은 없으므로 useEffect의 콜백함수에는 비동기 함수가 들어갈 수 없습니다 또한, 만약 useEffect에서 비동기 함수를 호출할 수 있다면 경쟁상태를 불러일으킬 수 있고 이로 인해 여러 문제가 발생할 수 있습니다. 이와 같은 이유로 비동기 함수는 useEffect 내에 들어갈 수 없습니다.

kwonhygge commented 1 day ago

useEffect의 콜백은 Promise를 반환하지 않는 함수입니다. 따라서 비동기함수가 들어갈 수 없습니다. 그 이유는 비동기함수의 응답이 오고있는 중에 dependency가 변경되면 원하지 않는 동작을 초래할 수 있기 때문입니다. 아래 코드에서 fetch의 응답이 오기 전에 dependency가 변경되어 두번째 useEffect가 호출되는 경우가 있습니다. 만일 이때 두번째 fetch의 응답이 먼저 도착한다면 state는 두번째 응답으로 업데이트 됩니다. 이후 첫번째 fetch의 응답이 도착하게 된다면 최신 데이터가 아닌 이전의 데이터가 업데이트 될 수 있습니다.

useEffect(() => {
  const fetchData = async () => {
    const response = await fetch("https://example.com/api/data");
    const data = await response.json();
    setState(data); // 상태 업데이트
  };

  fetchData();
}, [dependency]);