解决 React 中元素 scrollto 在渲染之前滚动的问题

注意看,这个人叫小帅。最近在撸一个工单系统的时候有个回复新信息把消息窗口滚动到最底部的需求。小帅在使用 scrollTo 的时候遇到了点问题。看看最后是怎么解决的吧!

当前工单系统分了三个区域,工单信息区/工单信息展示区(沟通记录)/用户回复区。
现在有个需求是用户在回复工单后需要把工单信息展示区的消息滚动到最底部以显示用户刚输入的信息。

那正常咱就是用 forwardref 拿到沟通记录区域的 htmlDivElement , 然后再等用户在下方的回复区发送异步请求后调用 scrollto 到 scrollheight 就实现了是吧。
但是实际操作遇到了点问题,如果按照刚才说的区域永远只会滚动到最新元素的上方,也就是最新的元素没有被计算在内。

排查了各种问题,使用 scrollTo 到 999999,依然是刚才的情况。
仔细想了想,可能是因为 元素滚动在渲染之前就完成了 , 拿到的 scrollheight 也只是刚才的高度。 知道问题那就好解决了。

解决问题

这次使用一个 MutationObserver 的 API 去监听 DOM 元素的变化。如果有变化了则直接执行回调函数。
同时也解决了刷新工单自动滚动到底部的效果。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
useEffect(() => {
const obs = new MutationObserver(() => {
// 滚动到底部
replyRef.current?.scrollTo({
top: replyRef.current.scrollHeight,
behavior: "smooth",
});
});

obs.observe(replyRef.current as Node, {
attributes: true,
childList: true,
subtree: true,
});

return () => {
obs.disconnect();
};
}, [replyRef]);

现在这个效果可灵动多了呢