본문 바로가기
Frontend/Javascript Typescript

[TIL] useEffect/onClick 내에서 비동기 처리

by 디스코비스킷 2024. 8. 8.
반응형

useEffect내에서 비동기 처리

useEffect 훅에서 비동기 함수 호출을 감싸는 이유를 전문적으로 설명하면 다음과 같다.

React의 useEffect 훅은 컴포넌트가 렌더링될 때 특정 작업을 수행할 수 있게 해주는 훅이다. useEffect의 리턴 값은 클린업 함수 또는 undefined여야 하며, 이는 다음 렌더링 전에 수행할 정리 작업을 정의한다. 따라서 useEffect는 프로미스(Promise)를 리턴할 수 없다.

비동기 함수를 직접적으로 useEffect에 전달하면 함수가 프로미스를 리턴하게 된다. 그러나 useEffect는 클린업 함수를 기대하므로 프로미스를 직접 반환하는 것은 올바르지 않다. 이에 따라 비동기 작업을 useEffect 내부에서 수행하려면 즉시 실행 함수(IIFE, Immediately Invoked Function Expression) 또는 다른 방법으로 비동기 함수를 호출해야 한다.

아래 코드를 예로 들어 설명하겠다.

useEffect(() => {
  (async () => {
    const user = await supabase.auth.getUser();
    setUserResponse(user);
  })(); // useEffect내에서는 이렇게 감싸야됨
}, []);

여기서 (async () => { ... })() 구문은 즉시 실행 비동기 함수 표현식이다. 이는 useEffect 내부에서 비동기 작업을 수행하면서도 useEffect가 기대하는 방식대로 작동하게 해준다.

useEffect 훅은 다음과 같은 이유로 즉시 실행 함수로 감싸 비동기 작업을 수행해야 한다:

  1. 프로미스 반환 방지: useEffect는 클린업 함수 또는 undefined를 리턴해야 한다. 비동기 함수는 프로미스를 반환하므로, 이를 직접 사용하면 useEffect가 프로미스를 리턴하게 되어 오류가 발생할 수 있다.
  2. 비동기 작업 수행: 컴포넌트가 마운트되거나 특정 상태 또는 프롭스가 변경될 때 비동기 작업을 안전하게 수행할 수 있다. 이 패턴을 사용하면 useEffect 내부에서 비동기 작업을 처리할 수 있다.

정리하면, useEffect 내부에서 비동기 작업을 수행할 때 비동기 함수를 즉시 실행 함수로 감싸는 것은 useEffect의 리턴 값 규칙을 준수하면서 비동기 작업을 수행하기 위한 권장 방법이다. 이 패턴은 컴포넌트의 마운트와 언마운트 시점에서 비동기 작업을 안전하게 처리하고, useEffect의 클린업 함수와의 충돌을 방지한다.

onClick함수 내에서 비동기 처리

비동기 함수를 onClick 핸들러로 사용하는 것은 특정 작업의 완료를 보장하고 그 다음 작업을 실행하는 데 중요하다. 이 경우, supabase.auth.signOut()가 비동기 함수이므로, 이를 비동기로 처리해야 로그아웃 작업이 완료된 후 페이지 이동이 일어날 수 있다. 이렇게 하지 않으면 로그아웃이 완료되기 전에 페이지 이동이 일어날 수 있어 예기치 않은 동작이 발생할 수 있다.

하지만 supabase.auth.signOut()router.push('/') 사이의 순서가 중요하지 않거나 로그아웃 요청을 기다릴 필요가 없는 경우, 비동기로 처리하지 않아도 된다. 다만, 안전하게 처리하기 위해서는 비동기로 처리하는 것이 좋다.

현재 작성한 코드에서는 비동기 처리(즉, asyncawait 키워드 사용)가 적절하게 되어 있다. 다음은 원래 코드이다:

<button
  onClick={async () => {
    await supabase.auth.signOut();
    router.push('/');
  }}
  className="rounded-md bg-gray-800 px-2 py-2 text-white"
>
  로그아웃
</button>

이 코드는 supabase.auth.signOut()가 완료된 후 router.push('/')가 실행되도록 한다. 비동기 처리를 제거하면 로그아웃 요청이 완료되기 전에 페이지 이동이 일어날 수 있다.

비동기 처리를 제거한 코드는 다음과 같다:

<button
  onClick={() => {
    supabase.auth.signOut();
    router.push('/');
  }}
  className="rounded-md bg-gray-800 px-2 py-2 text-white"
>
  로그아웃
</button>

위 코드에서는 supabase.auth.signOut()가 완료되기를 기다리지 않고 곧바로 router.push('/')가 실행된다. 이는 로그아웃 요청이 백그라운드에서 실행되지만, 사용자는 곧바로 홈 페이지로 이동하게 된다.

일반적으로는 비동기 처리를 유지하는 것이 좋다. 따라서 처음 작성한 코드를 사용하는 것을 권장한다.

반응형

최근댓글

최근글

© Copyright 2024 ttutta