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> ) }
额外优化点
- 移除了多余的
downloadedFilesCopy = [...downloadedFiles.items],直接遍历原数组即可 - 修改
downloadMetadata和findDownloadURL,直接使用传入的StorageReference对象,无需转成字符串重新创建ref - 给
map渲染的元素添加key属性,符合React列表渲染规范
内容的提问来源于stack exchange,提问作者Sean
相关产品推荐
相关产品推荐

