我正在实现一个文本编辑器,它的 JSX 计算速度可能有点慢。当 JSX 加载时,整个页面冻结。我正在尝试开发一个 Hook,让 JSX 滞后于文本,这样我就没有滞后尖峰问题。
显然这需要异步渲染 JSX。我还想始终使用已计算的最新版本的 JSX,而不计算每个 JSX 中间值。
到目前为止,这是我的 Hook 的演示。这一切都在 FunctionComponent 中。我觉得已经完成了,但是我想不通为什么useEffect会被一遍又一遍的调用,进入死循环。想法?
const slowComponent = async () => {
let i = 0
// while (i < 1000000000) i++
return <div>This component takes some time to load!</div>
}
const ref = useRef<{
isComputing: boolean,
todoSlowComponent: (() => Promise<React.ReactNode>) | null,
}>({
isComputing: false,
todoSlowComponent: null,
})
const [most_recent_slow_component, set_most_recent_slow_component] = useState<React.ReactNode>(null)
const computeInBG = async (slowComponent: () => Promise<React.ReactNode>) => {
ref.current.todoSlowComponent = slowComponent
if (ref.current.isComputing)
return
let req = ref.current.todoSlowComponent
ref.current.isComputing = true
ref.current.todoSlowComponent = null
const awaitedComponent = await req()
ref.current.isComputing = false
if (ref.current.todoSlowComponent !== null)
console.log('THIS CAN ACTUALLY PRINT DUE TO ASYNC BEHAVIOR!!!!')
if (ref.current.todoSlowComponent)
computeInBG(ref.current.todoSlowComponent)
set_most_recent_slow_component(awaitedComponent)
}
useEffect(() => { console.log('USE EFFECT'); computeInBG(slowComponent) })
return <>/*... */most_recent_slow_component</>
你的 useEffect 没有任何依赖数组。因此,如果组件中发生任何更改,它将再次调用。使其依赖于某些值,例如,
useEffect(() => {
computeInBG(slowComponent);
}, [text]);