在 React 中滚动到 div 的底部

在 React 中滚动到 div 的底部:

  1. 在 div 的底部添加一个元素。
  2. 在底部的元素上设置一个 ref
  3. 当事件发生时,调用 ref 对象的 scrollIntoView() 方法。
import {useEffect, useRef, useState} from 'react';

export default function App() {
  const bottomRef = useRef(null);

  const [messages, setMessages] = useState([]);

  useEffect(() => {
    // ?️ simulate chat messages flowing in
    setInterval(
      () =>
        setMessages(current => [
          ...current,
          'Lorem ipsum dolor sit amet consectetur, adipisicing elit. Porro, quaerat eum id obcaecati, magnam voluptatum dolorem sunt, omnis sed consectetur necessitatibus blanditiis ipsa? Cumque architecto, doloribus mollitia velit non sint!',
        ]),
      600,
    );
  }, []);

  useEffect(() => {
    // ?️ scroll to bottom every time messages change
    bottomRef.current?.scrollIntoView({behavior: 'smooth'});
  }, [messages]);

  return (
    <div>
      <h2>Top of the page</h2>

      <div>
        {messages.map((message, index) => {
          return <p key={index}>{message}</p>;
        })}

        <div ref={bottomRef} />
      </div>
    </div>
  );
}

在 React 中滚动到 div 的底部

这段代码展示了每次有新的聊天消息流入时如何滚动到 div 的底部。

对 useEffect 挂钩的第一次调用模拟每 600 毫秒出现的新消息。

我们使用 useRef 钩子初始化了一个 ref。

useRef() 钩子可以传递一个初始值作为参数。 该钩子返回一个可变的 ref 对象,其 .current 属性被初始化为传递的参数。

请注意,我们必须访问 ref 对象的 current 属性才能访问我们设置 ref 属性的 div 元素。

当我们将 ref prop 传递给元素时,例如 <div ref={myRef} />,React 将 ref 对象的 .current 属性设置为对应的 DOM 节点。

我们在第二个 useEffect 挂钩中添加了消息状态变量作为依赖项,因为我们希望每次消息更改时都重新运行挂钩中的代码。

useEffect(() => {
  bottomRef.current?.scrollIntoView({behavior: 'smooth'});
}, [messages]);

我们使用 scrollIntoView 方法滚动到聊天消息容器底部的 div 元素。

behavior 属性指定滚动应该平滑(smooth)还是立即发生(auto)。

behavior 属性的默认值为 auto

每次消息更改时,都会重新运行 useEffect 挂钩,我们调用 scrollIntoView() 方法滚动到 div 的底部并显示最新消息。