没有超时功能,无法在useEffect中设置HTMLElement的scrollTop

时间:2020-01-27 18:08:31

标签: reactjs typescript react-hooks use-effect

我有一个文本日志组件,每当它收到一个新的日志条目时,我都希望滚动到底部,因此我将它的父级scrollTop设置为scrollHeight中的useEffect() 。但是,这没有效果:

const Log = ({ entries }: LogProps) => {
    const logRef = useRef<HTMLDivElement>(null);
    useEffect(() => {
        if (logRef && logRef.current) {
            let parent = logRef.current.parentNode as HTMLDivElement
            parent.scrollTop = parent.scrollHeight;
        }
    })
    return (
        <Module className="log" title="Text Log">
            <div ref={logRef} className="log__entries">
                ...
            </div>
        </Module>

    )
}

另一方面,此代码有效:

...
useEffect(() => {
    if (logRef && logRef.current) {
        let parent = logRef.current.parentNode as HTMLDivElement
        setTimeout(() => {
            parent.scrollTop = parent.scrollHeight;
        }, 100)
    }     
})
...

在我的机器上,我可以将超时设置为39,这样它将一直工作。人数少则有零星的成功。大概这个数字会因性能指标而异,但我不知道。

控制台日志记录表明ref存在,并且它的高度足以在useEffect()触发时滚动。在parent.scrollTop = parent.scrollHeight;之前和之后进行记录表明scrollTop不变。

我误解了useEffect()的工作原理,是因为我要设置父母的scrollTop,还是我想念其他东西吗?

1 个答案:

答案 0 :(得分:0)

您可以通过进行一些更改来实现它:

useEffect(() => {
  logRef.current.scrollIntoView({ behavior: 'smooth', block: 'end' })
}, [entries])

您可以在Mozilla Docs上查看支持scrollIntoView功能的浏览器列表。 如果您希望更多的浏览器支持,则可以安装这个名为smoothscroll-polyfill的小npm软件包。

相关问题