我正在从 useEffect
调用 useCallback
,这将使组件的高度发生变化。然后,为了结束效果,我想将组件滚动到特定点。问题是滚动操作不起作用,因为它很快就会触发:DOM 尚未更新。
如果我将它包装在 setTimeout
中,它确实可以工作(因为一旦 DOM 更新它就会触发),但它有点 hacky。
有没有一种干净的方法可以等待 DOM 渲染后再追求效果?
不起作用:
const viewportElement = useRef()
cont [innerHeight, setInnerHeight] = useState(0)
refreshDOM = useCallback(() => {
setInnerHeight(500) // Will cause the DOM to refresh and the inner div to grow in height.
}, [setInnerHeight])
useLayoutEffect(() => {
refreshDOM() // DOM updates
viewportElement.current.scroll(0, 200) // Fires to soon: innerDiv is still too small
}, [refreshDOM, someOtherStuffTriggeringTheEffect])
return (
<div ref={viewportElement} style={{height: 100}}>
<div style={{height: innerHeight}}></div>
</div>
)
作品:
// ...
useLayoutEffect(() => {
refreshDOM() // DOM updates
setTimeout(
() => viewportElement.current && viewportElement.current.scroll(0, 200),
0,
) // DOM was refreshed, scroll operation works
}, [refreshDOM, someOtherStuffTriggeringTheEffect])
// ...
最佳答案
一个可能的解决方案是添加另一个 useEffect
并传递给依赖项 innerHeight
。当 innerHeight
更新时,这意味着您可以调用滚动:
useEffect(() => {
viewportElement.current.scroll(0, 200)
}, [innerHeight]);
并且不要忘记从 useLayoutEffect
中删除滚动
关于reactjs - 等待 DOM 上的 useCallback 效果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64926612/