React/React 문법

[React]useEffect Hook에서 async await를 사용하여 API 호출

DevStory 2021. 11. 18.

이번 포스팅에서는 useEffect Hook에서 async await를 사용하여 API 호출하는 방법을 소개합니다.

 

아래는 CodeSandBox에서 구현한 데모입니다.

데모 : https://codesandbox.io/s/useeffect-async-await-zpc0z

 


useEffect Hook에서 asnyc-await 함수 정의 이슈

순서 1.

우선, promise 구문을 사용한 코드입니다.

 

10개의 post 정보를 가져오기 위해 useEffect Hook에서 API 호출을 수행합니다.

useEffect(() => {
  axios
    .get("https://jsonplaceholder.typicode.com/posts/1/comments")
    .then((response) => {
      setPosts(response.data);
    });
}, []);

useEffect Hook에서 두 번째 인수로 빈 배열( [ ] )을 전달하여 컴포넌트가 마운트 될 때 한 번만 실행되도록 합니다.

 

빈 배열( [ ] )을 전달하면, 클래스 컴포넌트의 생명주기 함수인 componentDidMount와 동일하게 동작합니다.

 

순서 2.

1번에서 작성한 useEffect Hook을 async-await 구문으로 변환합니다.

useEffect(async () => {
  const posts = await axios.get("https://jsonplaceholder.typicode.com/users/1/posts");
  setPosts(posts.data);
}, []);

useEffect Hook 내부에 await 키워드를 사용할 수 있도록 콜백 함수를 비동기로 만들었습니다.

 

async-await 구문으로 변경하면 웹 브라우저에서는 정상적으로 동작하지만, 콘솔을 확인하면 아래 사진과 같은 경고를 볼 수 있습니다.

useEffect Hook은 아무것도 반환하지 않거나 Clean up 함수를 반환합니다.

 

그러나 async 키워드를 사용하면, promise 객체를 반환하므로 사진처럼 경고가 발생합니다.

반응형

경고 분석

async 키워드를 사용한 비동기 함수에서 promise 객체를 반환하는 내용에 대해 좀 더 자세하게 살펴보겠습니다.

 

다음은 간단한 간단한 예제입니다.

 

async구문을 사용하여 비동기 함수를 정의하고 비동기 함수가 반환하는 값을 확인하는 코드입니다.

const getResults = async() => { return "getResults함수가 반환하는 문자열"; };

const App = () => { 
  const result = getResults(); 
  console.log(result);
  return null;
};

App();

실행 결과

콘솔에 출력된 결과는 "getResults함수가 반환하는 문자열"이 아니라 Promise 객체임을 알 수 있습니다.

 

Promise 객체가 아니라 비동기 함수가 반환하는 값을 얻으려면 비동기 함수 호출하는 부분에 then을 연결해야 합니다.

const getResults = async() => { return "getResults함수가 반환하는 문자열"; };

const App = () => { 
  const result = getResults().then(response => console.log(response)); 
  return null;
};

App();

실행 결과

위에서 언급했지만, useEffect Hook은 Clean up 함수 이외에는 아무것도 반환하지 않으므로 then을 연결할 수 없습니다.

 

다음은 then을 사용하지 않고 경고를 해결하는 방법입니다.


해결 방법

1. 비동기 함수를 useEffect Hook 외부에 정의 후 useEffect Hook에서 호출합니다.

const getPosts = async () => {
  const posts = await axios.get(
    "https://jsonplaceholder.typicode.com/users/1/posts"
  );
  setPosts(posts.data);
};

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

 

2. 비동기 함수를 useEffect Hook 내부에 정의 후 useEffect Hook에서 호출합니다.

useEffect(() => {
  const getPosts = async () => {
    const posts = await axios.get(
      "https://jsonplaceholder.typicode.com/users/1/posts"
    );
    setPosts(posts.data);
  };
  
  getPosts();
}, []);

 

3. IFFE 사용

IFFE(Immediately Invoked Function Expression)은 함수가 정의되자마자 실행되는 자바스크립트 기술입니다.

useEffect(() => {
  (async () => {
    const posts = await axios.get(
      "https://jsonplaceholder.typicode.com/users/1/posts"
    );
    setPosts(posts.data);
  })();
}, []);
반응형

댓글