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

React中串联两个API请求的写法是否合理?求优化方案

React关联两个API请求的优化方案

你的代码存在一个潜在问题:第二个.then里访问data.compte.id时,setData是异步操作,此时data还没更新到最新值,可能导致第二个API请求拿不到正确的id,甚至报错。下面是几种更优的实现方式:

方式一:使用async/await(推荐)

async/await让异步代码逻辑更直观,同时直接用第一个请求的响应数据获取id,避开state异步更新的问题:

const [data, setData] = useState([]);
const [data2, setData2] = useState([]);

useEffect(() => {
  const fetchRelatedData = async () => {
    try {
      // 发起第一个API请求
      const firstResponse = await axios.get(api, config);
      setData(firstResponse.data);

      // 从第一个请求的响应中获取id,发起第二个请求
      const compteId = firstResponse.data.compte.id;
      const secondResponse = await axios.get(`http://localhost:8000/api/compte/${compteId}`, config);
      setData2(secondResponse.data);
    } catch (error) {
      console.error('请求失败:', error);
    }
  };

  fetchRelatedData();
}, []);

方式二:规范链式调用

如果习惯用.then链式写法,要把第二个请求放在第一个请求的.then内部,直接使用响应数据而非state:

const [data, setData] = useState([]);
const [data2, setData2] = useState([]);

useEffect(() => {
  axios.get(api, config)
    .then(firstResponse => {
      setData(firstResponse.data);
      // 直接用响应里的id发起第二个请求,并返回Promise继续链式调用
      return axios.get(`http://localhost:8000/api/compte/${firstResponse.data.compte.id}`, config);
    })
    .then(secondResponse => {
      setData2(secondResponse.data);
    })
    .catch(error => {
      console.error('请求失败:', error);
    });
}, []);

额外优化建议

  • 添加请求取消逻辑:避免组件卸载后未完成的请求导致内存泄漏:
    useEffect(() => {
      const cancelTokenSource = axios.CancelToken.source();
    
      const fetchRelatedData = async () => {
        try {
          const firstResponse = await axios.get(api, { ...config, cancelToken: cancelTokenSource.token });
          setData(firstResponse.data);
    
          const compteId = firstResponse.data.compte.id;
          const secondResponse = await axios.get(`http://localhost:8000/api/compte/${compteId}`, { ...config, cancelToken: cancelTokenSource.token });
          setData2(secondResponse.data);
        } catch (error) {
          // 忽略取消请求的错误
          if (!axios.isCancel(error)) {
            console.error('请求失败:', error);
          }
        }
      };
    
      fetchRelatedData();
    
      // 组件卸载时取消所有未完成的请求
      return () => cancelTokenSource.cancel('组件已卸载,取消请求');
    }, []);
    
  • 合并关联状态:如果两个请求的数据是强关联的,可以合并成一个state对象,简化状态管理:
    const [combinedData, setCombinedData] = useState({ mainData: [], compteData: [] });
    
    // 更新状态时:
    setCombinedData(prev => ({ ...prev, mainData: firstResponse.data }));
    setCombinedData(prev => ({ ...prev, compteData: secondResponse.data }));
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 15:15:59