React项目获取数据后无法渲染页面及async/await报错求助
React异步数据渲染问题解决
问题描述
在React项目中通过axios获取产品数据,控制台能正常打印出处于fulfilled状态的Promise数据,但无法在页面上渲染这些数据。若在Homepage组件中使用async/await,会触发错误:Objects are not valid as a React child (found: [object Promise])。
相关代码
pages/index.js
import React from 'react'; import axios from 'axios'; import ListProducts from '@/components/products/ListProducts'; const getProducts = async () => { const data = await axios.get(`${process.env.API_URL}/api/products`); return data }; const Homepage = () => { const productsData = getProducts(); return <ListProducts data={productsData} />; }; export default Homepage;
ListProducts组件
"use client"; import React from "react"; import Filters from "./Filters"; import ProductItem from "./ProductItem"; const ListProducts = ({ data }) => { console.log(data); return ( <section className="bg-green-50 py-12 "> <article className="max-w-screen-3xl mx-auto px-4 flex "> <Filters /> <article className="grid grid-cols-2"> {data?.products?.map((product) => ( <ProductItem key={product?._id} product={product} /> ))} </article> </article> </section> ); }; export default ListProducts;
ProductItem组件
const ProductItem = ({ product }) => { return ( <article className="border border-gray-200 overflow-hidden bg-slate-300 shadow-md rounded mb-5 grid w-full"> <img src="https://i.pinimg.com/564x/89/2a/a5/892aa521d0a9c24646c7dd153b8f442a.jpg" alt="" /> <p className="text-white text-lg"> {product?.name}</p> </article> ); }; export default ProductItem;
控制台输出
Promise {<fulfilled>: {…}} [[Prototype]]: Promise [[PromiseState]]: "fulfilled" [[PromiseResult]]: Object config: {transitional: {…}, adapter: Array(2), transformRequest: Array(1), transformResponse: Array(1), timeout: 0, …} data: products: (3) [{…}, {…}, {…}] [[Prototype]]: Object headers: AxiosHeaders {content-length: '567', content-type: 'application/json; charset=utf-8', date: 'Sun, 29 Oct 2023 07:35:26 GMT', etag: '"76gcorsd0nfr"', vary: 'Accept-Encoding'} request: XMLHttpRequest {onreadystatechange: null, readyState: 4, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload, …} status: 200 statusText: "OK" [[Prototype]]: Object
解决方案
核心问题分析
- 直接调用
getProducts()返回的是Promise对象,而非实际的产品数据,所以ListProducts组件中data是Promise,无法通过map渲染列表。 - React组件不能是
async函数——组件必须返回JSX元素,而async函数返回的是Promise,这就是报错Objects are not valid as a React child的原因。
修改代码实现正确渲染
1. 调整Homepage组件,用useState+useEffect处理异步请求
import React, { useState, useEffect } from 'react'; import axios from 'axios'; import ListProducts from '@/components/products/ListProducts'; const getProducts = async () => { const response = await axios.get(`${process.env.API_URL}/api/products`); // 只返回后端返回的实际数据,而非整个axios响应对象 return response.data; }; const Homepage = () => { const [products, setProducts] = useState([]); const [loading, setLoading] = useState(true); useEffect(() => { // 在useEffect内部定义异步函数处理请求 const fetchProducts = async () => { try { const data = await getProducts(); // 更新状态,存入产品列表 setProducts(data.products); } catch (error) { console.error('获取产品数据失败:', error); } finally { // 请求完成后结束加载状态 setLoading(false); } }; fetchProducts(); }, []); // 空依赖数组确保只在组件挂载时执行一次 // 加载状态提示 if (loading) { return <div>加载中...</div>; } // 将产品列表传入子组件 return <ListProducts data={{ products }} />; }; export default Homepage;
2. 优化ListProducts组件(可选)
可以添加空数据判断,提升用户体验:
"use client"; import React from "react"; import Filters from "./Filters"; import ProductItem from "./ProductItem"; const ListProducts = ({ data }) => { const { products } = data; return ( <section className="bg-green-50 py-12 "> <article className="max-w-screen-3xl mx-auto px-4 flex "> <Filters /> <article className="grid grid-cols-2"> {products.length === 0 ? ( <p>暂无产品数据</p> ) : ( products.map((product) => ( <ProductItem key={product?._id} product={product} /> )) )} </article> </article> </section> ); }; export default ListProducts;
内容的提问来源于stack exchange,提问作者argyris
相关产品推荐
相关产品推荐

