Alex
Alex

Reputation: 27

Next.js 13: "Objects are not valid as a React child" error when fetching data with async/await

I am using Next.js 13 with the new app directory and I'm trying to fetch data from my API. But when i try using async/await i keep getting the error: "Objects are not valid as a React child (found: [object Promise]). If you meant to render a collection of children, use an array instead."

async function getProducts() {
  const { data } = await storefront(productsQuery);
  return data.products;
}

export default async function Page({ params }: any) {
    const fetchedData = await getProducts();

    return (<>
        {fetchedData.edges.map((item: any) => (
            <Text>{item.node.title}</Text>
        ))}
    </>);
}

This is my code. The data I receive from the api is:

"data": {         
  "products": {             
   "edges": [                 
    {                     
     "node": {                         
      "title": "Some title",                     
     }                 
    }             
   ]         
  }     
 } 
}

I've tried converting the title to a string using toString() and using a key attribute in the map function, but the error persists. Also, I have a 'use client'; at the top of each file since I'm using Chakra UI but this doesn't seem to be the source of the problem.

What am I doing wrong? How can I properly fetch and render the data in my Next.js app?

Thank you in advance for your help!

Upvotes: 1

Views: 87

Answers (2)

Dinanjana
Dinanjana

Reputation: 162

By having the async keyword function Page which is a component you are implying that this function returns a promise rather than a react component. Your function now wraps your result react component array inside a promise. Functional components can't return promises.

Upvotes: 3

user7247147
user7247147

Reputation: 1107

You need to make sure that the fetched data is available. For example:

export default function Page({ params }: any) {
  const [fetchedData, setFetchedData] = useState([]);

  useEffect(() => {
    (async () => {
      const data = await getProducts();
      setFetchedData(data.edges);
    })();
  }, []);

  return (<>
        {fetchedData.edges.map((item: any) => (
            <Text>{item.node.title}</Text>
        ))}
    </>);
}

Upvotes: 2

Related Questions