我有一个文本日志组件,每当它收到一个新的日志条目时,我都希望滚动到底部,因此我将它的父级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
,还是我想念其他东西吗?
答案 0 :(得分:0)
您可以通过进行一些更改来实现它:
useEffect(() => {
logRef.current.scrollIntoView({ behavior: 'smooth', block: 'end' })
}, [entries])
您可以在Mozilla Docs上查看支持scrollIntoView
功能的浏览器列表。
如果您希望更多的浏览器支持,则可以安装这个名为smoothscroll-polyfill的小npm软件包。