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

React中向状态添加新数组未触发重渲染问题求助

React状态更新后未触发重渲染的问题解决

问题根源

你的核心问题出在downloadFiles函数的forEach循环上——forEach不支持异步等待逻辑,当你调用setUserFiles时,循环内的downloadMetadata和findDownloadURL异步操作还未执行完成,此时newFileList仍是空数组。后续异步操作完成后往newFileList中push数据,但状态已经完成设置,且没有再次触发状态更新,组件自然不会重渲染。

修正方案

将forEach替换为map结合Promise.all,等待所有异步操作完成后再更新状态:

const UpdateProfile = () => {
  const [userFiles, setUserFiles] = useState<any>([])

  async function downloadFiles() {
    try {
      const downloadedFiles = await listAll(storageRef);
      // 用map生成异步Promise数组,通过Promise.all等待全部完成
      const newFileList = await Promise.all(downloadedFiles.items.map(async (file) => {
        const downloadedFileMetadata = await downloadMetadata(file);
        downloadedFileMetadata.url = await findDownloadURL(file);
        return downloadedFileMetadata;
      }));
      setUserFiles(prev => [...prev, ...newFileList]);
    } catch(e) {
      alert(e)
    }
  }

  // 优化:直接传入StorageReference,无需重新创建ref
  async function downloadMetadata(item: StorageReference) {
    try {
      return await getMetadata(item);
    } catch(e) {
      alert(e)
    }
  }

  async function findDownloadURL(item: StorageReference) {
    try {
      return await getDownloadURL(item);
    } catch(e) {
      alert(e)
    } 
  }

  useEffect(() => {
    getProfileDetails()
    downloadFiles()
  }, [])
  
  return (
    <Container id="update-page-container">
        {userFiles.map((file: any, index) => <p key={index}>File here</p>)}
    </Container>
  )
}

额外优化点

  1. 移除了多余的downloadedFilesCopy = [...downloadedFiles.items],直接遍历原数组即可
  2. 修改downloadMetadata和findDownloadURL,直接使用传入的StorageReference对象,无需转成字符串重新创建ref
  3. 给map渲染的元素添加key属性,符合React列表渲染规范

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 23:47:34