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

React中.map()内通过setState实现单条列表项下载请求独立显示加载Spinner

解决方案

1. 调整加载状态的存储结构

把原来布尔类型的全局加载状态,替换为存储正在加载的报告ID集合的状态,这样可以精准标记哪个项正在加载:

// 原来的布尔状态(可删除)
// const [downloadLoadingState, setDownloadLoadingState] = useState(false)
// 替换为Set结构存储正在下载的ID
const [downloadingIds, setDownloadingIds] = useState<Set<string>>(new Set())

如果加载状态是从父组件通过props传递,只需把父组件的状态对应修改为上述Set结构即可。

2. 修改下载请求逻辑

请求发起时把当前报告ID加入集合,请求结束(无论成功失败)时把ID从集合移除,遵循React状态不可变更新原则:

const onDownload = (reportId: string) => {
    // 加入当前ID到加载集合
    setDownloadingIds(prev => {
        const newSet = new Set(prev)
        newSet.add(reportId)
        return newSet
    })

    backendAPIAxios.get(`/download/${reportId}`)
    .then((response: AxiosResponse<IDownloadResponse>) => { 
        // 原有下载成功的处理逻辑保留
    })
    .catch((e: AxiosError) => {
        // 原有错误处理逻辑保留
    })
    .finally(() => {
        // 从加载集合移除当前ID
        setDownloadingIds(prev => {
            const newSet = new Set(prev)
            newSet.delete(reportId)
            return newSet
        })
    });
}; 

3. 调整渲染判断逻辑

仅判断当前项的ID是否存在于加载集合中,即可控制单个项的加载状态显示:

<Button>
  {!downloadingIds.has(history.id!) ?
    <MSvg
      name='download'
      className={classes['svgContainerBlack']} 
      onClick={() => onDownload(history.id!)}
    /> :
  <Tooltip title={<h1 style={{ fontSize: '17px' }}>Loading</h1>} placement="left" arrow>
    <CircularProgress color="inherit" />
  </Tooltip>
 }
</Button>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 20:45:10