调用返回setTimeout回调的JS函数时的React渲染问题
解决方案
问题本质
generate函数调用后返回的是接收回调函数的高阶函数,既不是Promise实例,也不是直接返回生成的数值,所以直接调用、直接await都无法拿到预期结果- React 不支持直接在JSX中渲染异步结果,所有异步获取的值需要通过状态更新触发重渲染后才能正常展示
具体实现
第一步:将回调风格的调用包装为Promise
const wrapGenerate = () => { return new Promise(resolve => { // generate()返回高阶函数,直接将resolve作为回调传入 generate()(resolve) }) }
第二步:在React组件中通过状态管理异步结果
import { useState, useEffect } from 'react' const Test = () => { const [result, setResult] = useState(null) const [isLoading, setIsLoading] = useState(true) useEffect(() => { // 标记组件是否卸载,避免更新已卸载组件的状态触发警告 let isUnmounted = false const getResult = async () => { const num = await wrapGenerate() if (isUnmounted) return setResult(num) setIsLoading(false) } getResult() // 清理函数 return () => { isUnmounted = true } }, []) if (isLoading) { return <>加载中,预计等待7-14秒...</> } return <>{result}</> }
常见问题说明
- 不能直接在组件顶层写await:React函数组件是同步执行的,顶层await会阻塞组件渲染,不符合React的渲染逻辑
- 不需要修改原有
generate函数:以上方案完全基于现有不可修改的generate函数实现,无需调整原函数逻辑
内容的提问来源于stack exchange,提问作者Chris McGlade
相关产品推荐
相关产品推荐

