如何在 React 中实现 scrollTo 效果
之前考虑过用scrollInToView,但是由于这个 API 实现的场景不能控制元素在屏幕上的显示位置遂选择其他出路。
scrollTo 当只有一个元素需要直接滚动时 可以在 useEffect 直接调用 该方法即可。
当遇到需要控制一个有序数组的时候该如何操作。需求如下
- 可以点击按钮进行依次循环滚动。
- 需要控制住滚动时距离顶部的高度。
- 需要滚动的数组变化时,需要在滚动列表中添加或删除一条记录。

例如,在git MR 的详情页上有几个未解决的评论。在tab 页上需要一个快捷的点击按钮进行快速定位到需要解决的评论上去。
然而会遇到几个场景。
场景一:当页面上只需要定位到具体的某几条评论,不涉及评论解决后,跳转发生变化。这种是最简单的场景。我们实现的方案也会比较的简单。
即判定评论列表是否显示后,展示在 tab上一个跳转 btn 。然后把 未解决的评论通过一个字段筛选出来传入到一个记录的state 中. 其中通过 hook的 useEffect 计算出。一个未解决评论的位置数组。其中这个位置数组只根据 第一次 传入的 unResolved 计算一次。
这个时候你们可能会问怎么保证这个位置数组只计算一次。
// 设置一个 是否可以计算 dom 的标志位
const [canCountDom, setCanCountDom] = useState(false)
useEffect(() => {
unResolved.length > 0 && setCanCountDom(true)
}, [unResolved])
其中计算dom 位置的方法是下述代码
useEffect(() => {
unResolved.length > 0 && setBackUnResolved(unResolved)
unResolved.length > 0 &&
setDomPostionArr(
unResolved.map((v) => {
const dom = document.getElementById(v.id)
const postion = dom && dom.getBoundingClientRect().top
return { dom, postion }
})
)
}, [canCountDom])
这样写的话是当未解决的数组有数据时,只计算出一次有数据时的位置信息。这样的话可以保证跟 gitlab上调整到未解决的下一个的效果一致。这样做法我们忽视了commit 列表上有两种搜索方法。

按照时间,按照是否显示所有活动或者是只展示 diff 上评论四种场景。说了这么多其实就是评论的dom 可能在可视范围内消失。或者记录时的位置跟后面排序的位置不在同一个地方。例如时间倒序,原本的第一个未解决的评论就直接跳转到最后一个位置。这样咋们第一次记录的位置就无效了。
现在遇到的问题是这样的。react 中当滚动的元素已解决时整个滚动列表发生变化时
如果采用实时计算dom 位置的方法,当元素在可视范围的头部时,其值为 负。这个时候可能会说好解决直接向下滚动计算的负值不就可以了吗。那要是用户手动滚动到顶部你计算的负值瞬间没用了。。。
时间太紧,没有写完补充中。。。。