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

如何在模板循环参数时通过异步函数返回Promise数据并渲染

在React模板循环中异步获取数据并渲染的解决方案

你当前的写法直接在JSX中调用异步函数getByModelNo,会返回一个Promise对象,无法直接访问.seriesName属性——因为Promise还未完成状态转换,拿到的不是实际接口返回的数据。以下是两种可行的解决方式:

方案一:提前批量获取所有数据后渲染

这种方式会在组件挂载时一次性请求所有item的详情数据,存到状态中后再渲染,适合数据量较小的场景:

import { useState, useEffect } from 'react';
import axios from 'axios';

// 假设prefix和DataFromModel类型已定义
const prefix = '/api';
type DataFromModel = { seriesName: string };

const YourComponent = () => {
  // 原始列表数据
  const [rawData] = useState([
    { id: 1, model: "DIY-MULTI3-27HP230C" }
  ]);
  // 存储包含详情的最终数据
  const [processedData, setProcessedData] = useState<(typeof rawData[0] & DataFromModel)[]>([]);

  const getByModelNo = async ({ id, params }: { id: string, params?: AxiosRequestConfig }) => {
    const options = {
      method: 'GET',
      url: `${prefix}/${id}`,
      params
    };
    try {
      const response = await axios.request(options);
      return response?.data?.data;
    } catch (error) {
      console.error('请求详情失败:', error);
      return {};
    }
  };

  useEffect(() => {
    const fetchAllDetails = async () => {
      // 生成所有请求的Promise数组
      const requestPromises = rawData.map(async item => {
        const details = await getByModelNo({ id: item.model });
        // 合并原始数据与详情数据
        return { ...item, ...details };
      });
      // 等待所有请求完成
      const results = await Promise.all(requestPromises);
      setProcessedData(results);
    };

    fetchAllDetails();
  }, [rawData]);

  return (
    <div>
      {processedData.map((item, index) => (
        <div key={index}>{item.seriesName}</div>
      ))}
    </div>
  );
};

export default YourComponent;

方案二:封装异步子组件单独处理请求

这种方式把每个item的请求、加载状态、渲染逻辑封装到独立组件中,适合数据量大或需要单独处理每个item加载/错误状态的场景:

import { useState, useEffect } from 'react';
import axios from 'axios';

const prefix = '/api';
type DataFromModel = { seriesName: string };

// 封装单个item的异步组件
const ItemDetail = ({ model }: { model: string }) => {
  const [seriesName, setSeriesName] = useState('');
  const [isLoading, setIsLoading] = useState(true);

  const getByModelNo = async ({ id, params }: { id: string, params?: AxiosRequestConfig }) => {
    const options = {
      method: 'GET',
      url: `${prefix}/${id}`,
      params
    };
    try {
      const response = await axios.request(options);
      return response?.data?.data;
    } catch (error) {
      console.error('请求详情失败:', error);
      return {};
    }
  };

  useEffect(() => {
    const fetchDetail = async () => {
      const details = await getByModelNo({ id: model });
      setSeriesName(details.seriesName || '');
      setIsLoading(false);
    };

    fetchDetail();
  }, [model]);

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

  return <div>{seriesName}</div>;
};

// 父组件
const YourComponent = () => {
  const data = [
    { id: 1, model: "DIY-MULTI3-27HP230C" }
  ];

  return (
    <div>
      {data.map((item, index) => (
        <ItemDetail key={index} model={item.model} />
      ))}
    </div>
  );
};

export default YourComponent;

方案对比

  • 方案一:一次性加载所有数据,用户等待时间稍长,但渲染时无局部加载状态,适合小数据量场景。
  • 方案二:每个item独立请求,可单独显示加载/错误状态,用户体验更友好,适合大数据量或需要精细化状态管理的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 16:23:21