You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中使用Axios获取数据先返回空数组再返回数据的问题

React组件先打印空数组再获取商品数据的原因及解决办法

原因分析

这是React正常渲染逻辑导致的:

  • 组件首次渲染时,products1的初始状态是你设置的空数组[],此时执行console.log(products1)自然输出空数组。
  • useEffect钩子会在组件挂载完成后才触发,里面的axios.get是异步请求,需要等待接口返回数据。请求完成后调用setProducts1(data)更新状态,这会触发组件重新渲染,此时products1已经是接口返回的商品对象,所以第二次打印会输出正确数据。

解决办法

方法1:监听状态变化打印数据

通过额外的useEffect监听products1的变化,只有当数据更新时才打印:

import { useState, useEffect } from "react";
import { Container, Row, Col } from "react-bootstrap";
import axios from "axios";
import { useParams } from "react-router-dom";

const ProductScreen = () => {
  const params = useParams();
  const [products1, setProducts1] = useState([]);

  useEffect(() => {
    const fetchProducts = async () => {
      const { data } = await axios.get(`/api/products/${params.id}`);
      setProducts1(data);
    };
    fetchProducts();
  }, [params.id]);

  // 监听products1变化,数据更新后打印
  useEffect(() => {
    console.log(products1);
  }, [products1]);

  return <h1>Hello</h1>;
};

export default ProductScreen;

方法2:处理加载状态,确保数据就绪后再使用

如果需要在组件中使用商品数据,更合理的方式是先处理加载状态,避免使用未就绪的数据:

import { useState, useEffect } from "react";
import { Container, Row, Col } from "react-bootstrap";
import axios from "axios";
import { useParams } from "react-router-dom";

const ProductScreen = () => {
  const params = useParams();
  const [products1, setProducts1] = useState(null);
  const [isLoading, setIsLoading] = useState(true);

  useEffect(() => {
    const fetchProducts = async () => {
      try {
        const { data } = await axios.get(`/api/products/${params.id}`);
        setProducts1(data);
      } catch (error) {
        console.error("获取商品数据失败:", error);
      } finally {
        setIsLoading(false);
      }
    };
    fetchProducts();
  }, [params.id]);

  // 加载中状态
  if (isLoading) {
    return <h1>加载中...</h1>;
  }

  // 数据为空时的处理
  if (!products1) {
    return <h1>商品不存在</h1>;
  }

  // 此时数据已就绪,打印或渲染都没问题
  console.log(products1);
  return (
    <Container>
      <Row>
        <Col>
          <h1>{products1.product_name}</h1>
          <p>价格:{products1.price}</p>
          {/* 渲染其他商品信息 */}
        </Col>
      </Row>
    </Container>
  );
};

export default ProductScreen;

方法3:利用setState的回调函数(不推荐用于复杂逻辑)

如果只是想在更新状态时立刻看到数据,可以使用setState的回调形式:

setProducts1((prevData) => {
  const newData = data;
  console.log(newData); // 这里能拿到最新的商品数据
  return newData;
});

内容的提问来源于stack exchange,提问作者Develop96

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 20:24:33