reactjs - 没有超时功能,无法在 useEffect 中设置 HTMLElement 的 scrollTop
问题描述
我有一个文本日志组件,只要它收到新的日志条目,我就想滚动到底部,所以我将它的父级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
,还是我还缺少其他东西?
解决方案
您可以通过进行一些更改来实现它:
useEffect(() => {
logRef.current.scrollIntoView({ behavior: 'smooth', block: 'end' })
}, [entries])
您可以在Mozilla DocsscrollIntoView
中查看支持功能的浏览器列表。如果你想要更多的浏览器支持,那么你可以安装这个名为smoothscroll-polyfill 的小型 npm 包。
推荐阅读
- dart - 使用颤振的多用户应用程序
- python - 检查随机生成的数组中是否存在值
- php - PHP全局关键字如何在使用范围的函数内工作?
- python - 如何将 Pandas 系列转换为 Dataframe 以进行合并
- c - 在 68HC16 上使用 gcc 2.8.1;制作安装问题
- bokeh - 如何在 HoloViews 中设置散景刻度和字体选项?
- react-native - 如何在 react-native 中修复“CredentialsError:配置中缺少凭据”(aws-sdk)
- laravel - 运行迁移后填充表
- docker - init: true 不转发信号
- python-3.x - 如何有条件地从多个 Python 字典中删除键。条件是 (Value <= time.time()- 15)