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

Axios响应未解析问题:React中数据获取与过滤异常排查

问题描述

我使用Axios获取太阳系天体数据并进行过滤时遇到多个异常:

  • 初始状态下,返回的数组包含数据但长度显示为0
  • 添加if(data)判断后,数据先显示为null,一段时间后恢复正常
  • 加入if(response && response.ok)判断后,页面完全无内容,推测是Promise未正确解析导致

以下是我的React代码:

import React, { useState, useEffect } from "react";
import axios from "axios";
import ChildComponent from "./Boxes.jsx";

function Data() {
  const path = "https://api.le-systeme-solaire.net/rest/bodies/";
  const [data, setData] = useState(null);
  const [isLoading, setIsLoading] = useState(true);
  const [complexBodies, setComplexBodies] = useState([]);
  const [simpleBodies, setSimpleBodies] = useState([]);

  useEffect(() => {
    const fetchData = async () => {
      await axios
        .get(path)
        .then((response) => {
          if (response && response.ok) {
            setData(response.data.bodies);
            setIsLoading(false);
          }
        })
        .catch((error) => console.log(error));
    };
    fetchData();
    if (data) dataFilter();
  }, [path]);

  const dataFilter = () => {
    try {
      console.log(data);
      const filterComplex = (body) => body.moons != null;
      const complexBodies = data.filter(filterComplex);
      setComplexBodies((props) => [...props, ...complexBodies]);
      console.log(complexBodies.length);
      const filterSimple = (body) => body.moons == null;
      const simpleBodies = data.filter(filterSimple);
      console.log(simpleBodies.length);
      setSimpleBodies((props) => [...props, ...simpleBodies]);
      console.log(simpleBodies);
    } catch (error) {
      console.log("Error al filtrar");
    }
  };

  if (isLoading) {
    return <></>;
  }
  console.log(complexBodies);
  return (
    <div className="Data">
      <ChildComponent
        simpleBodies={simpleBodies}
        complexBodies={complexBodies}
      />
    </div>
  );
}

export default Data;
问题分析与修复

1. 异步逻辑执行顺序错误

useEffect中调用fetchData后立刻执行dataFilter(),但fetchData是异步操作,此时data仍为初始的null,dataFilter根本不会执行。且React的setState是异步的,组件重新渲染后才会拿到更新后的data,这是导致数据异常的核心原因。

2. Axios响应判断冗余且错误

Axios仅在请求成功(状态码2xx)时进入then分支,response.ok判断完全多余。若接口返回非2xx状态码会直接进入catch,但你的判断会导致部分合法响应无法设置数据,isLoading一直为true,页面空白。

3. 数据过滤时机错误

过滤逻辑不应在useEffect中直接调用,而应在数据获取完成后立即执行,或监听data的变化触发过滤。

4. setState用法错误

设置complexBodies和simpleBodies时使用[...props, ...complexBodies]会导致数据重复累加,直接设置为过滤后的数组即可。

修复后的代码

import React, { useState, useEffect } from "react";
import axios from "axios";
import ChildComponent from "./Boxes.jsx";

function Data() {
  const path = "https://api.le-systeme-solaire.net/rest/bodies/";
  const [isLoading, setIsLoading] = useState(true);
  const [complexBodies, setComplexBodies] = useState([]);
  const [simpleBodies, setSimpleBodies] = useState([]);

  useEffect(() => {
    const fetchData = async () => {
      try {
        const response = await axios.get(path);
        const bodies = response.data.bodies;
        
        // 直接过滤数据,无需存储原始data到state
        setComplexBodies(bodies.filter(body => body.moons != null));
        setSimpleBodies(bodies.filter(body => body.moons == null));
        setIsLoading(false);
      } catch (error) {
        console.log("请求错误:", error);
        setIsLoading(false); // 出错后终止加载状态
      }
    };
    fetchData();
  }, [path]);

  if (isLoading) {
    return <div>加载中...</div>; // 替换空内容,提供加载反馈
  }

  return (
    <div className="Data">
      <ChildComponent
        simpleBodies={simpleBodies}
        complexBodies={complexBodies}
      />
    </div>
  );
}

export default Data;

额外优化说明

  • 移除冗余的data state,直接在请求后处理过滤,简化状态管理
  • 统一使用async/await + try/catch替代then/catch,代码逻辑更清晰
  • 加载状态返回提示文本,避免页面空白
  • 异常分支设置isLoading为false,防止页面一直处于加载状态

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 19:03:18