React

"Objects are not valid as a React child (found: [object Promise])" 비동기 작업이 완료되기 전에 프로미스 객체가 렌더링되어 발생하는 문제

쿠키는 서비스 2024. 2. 14. 11:54
반응형

"Objects are not valid as a React child (found: [object Promise])"

위와 같은 에러가 발생했다.

이 에러는 비동기 작업이 완료되기 전에 프로미스 객체가 렌더링되어 발생하는 문제다.

주로 useEffect 내에서 비동기 작업을 수행하고 해당 작업이 완료되기 전에 컴포넌트가 렌더링되면서 에러가 발생한다.

 

1. 'useEffect' 내에서 비동기 작업을 수행한다.

2. 해당 작업이 완료되기 전에 컴포넌트가 렌더링된다.

3. 렌더링 시점에넌 아직 프로미스가 해결되지 않아 `[object Promise]`가 렌더링되어 오류가 발생한다.

 

해결방법은 비동기 작업이 완료된 후에 상태를 업데이트하고, 그 상태를 렌더링하면 된다.

예를 들어 다음과 같이 고쳐보자.

import React, { useState, useEffect } from 'react';
import { readProductData } from '../auth/firebaseAuth';

export default function Products() {
  const [products, setProducts] = useState([]);

  useEffect(() => {
    const getProductData = async () => {
      try {
        const productData = await readProductData();
        setProducts(productData);
      } catch (error) {
        console.error('Error fetching product data:', error);
      }
    };

    getProductData();
  }, []);

  return (
    <div>
      제품 페이지
      {products.length > 0 ? (
        products.map((product, index) => (
          <div key={index}>
            {/* 제품 데이터를 여기에 렌더링하세요 */}
            {/* 예: <p>{product.name}</p> */}
          </div>
        ))
      ) : (
        '로딩 중...'
      )}
    </div>
  );
}

포인트는 useEffect 내에서 함수를 하나 만들어주고 그 함수를 호출해주자.

useEffect(async()=>{await ...}, []) 이런 식으로 쓰면 안된다.

 

useEffect(async()=>{},[]) 이렇게 쓰면 안되는 이유?

useEffect는 함수 내부에서 비동기 작업을 직접 수행할 수 없다. useEffect의 첫 번째 인자로 전달되는 함수는 promise를 반환해서는 안 된다. 따라서 useEffectasync 키워드를 사용하고 내부에서 await를 사용하는 것은 올바른 사용 방법이 아니다.

 

useEffect의 콜백 함수는 프로미스를 반환할 수 없는 이유?

  1. 동기적인 특성: useEffect의 주요 목적 중 하나는 부수 효과(side effect)를 처리하는 것이다. 이 부수 효과는 주로 비동기적인 작업이 포함되어 있다. 그러나 useEffect는 동기적으로 작동하도록 설계되었다. 따라서 콜백 함수가 프로미스를 반환하면 해당 프로미스가 완료될 때까지 기다리지 않고 바로 다음 코드로 진행된다.
  2. 비동기 코드의 관리: useEffect 콜백 함수가 비동기적으로 동작할 경우, 코드의 실행 흐름이 예측 가능하지 않아서 상태 변화 및 컴포넌트 랜더링에 대한 제어가 어려워진다. 리액트는 렌더링 주기를 동기적으로 관리하고, 비동기 코드로 인해 예측 불가능한 상태 변화가 발생하면 애플리케이션의 상태 관리가 어려워질 수 있다.

대신에, 비동기 작업은 콜백 함수 내부에서 직접 수행하는 것이 아니라, 해당 함수 내부에서 비동기 함수를 호출하고 그 함수가 프로미스를 반환하도록 하는 것이 권장된다. 이렇게 하면 비동기 작업의 완료를 기다리지 않고도 코드의 예측 가능성을 유지하면서 비동기 작업을 처리할 수 있음!

반응형