滚动到映射数组的最后一项
Scroll to the last item of a mapped array
我有一个 Message
组件,它在一个线程中显示所有消息(传入和传出)。
我希望最后 message/a 条新输入的 message/incoming 消息始终显示在对话的底部。有点像所有 chats/messaging 应用程序所做的。
这是我的代码:
import React, { useRef } from "react";
const dummy = useRef();
...
dummy?.current?.scrollIntoView(true, {
behaviour: "auto",
});
...
<div className="">
<Paper
elevation={0}
sx={{
backgroundColor: "#fafafa",
maxHeight: 200,
overflow: "auto",
}}
>
{messages.map((message, idx) => (
<div key={idx} ref={dummy}>
<Message message={message} name={name} />
</div>
))}
{/* I tried this also
<div ref={dummy}></div> */}
</Paper>
</div>
我希望当我单击 conversation/thread 时,所有可以放入带有 maxHeight: 200
的父 div 的消息,最后一条消息显示在底部。目前,整个页面滚动到底部,而不仅仅是线程中的消息。页面应保持静止。
我该怎么做?
问题是您将 ref
传递给呈现 Message
组件的 div
元素。我建议你在聊天结束时使用虚拟 div
,然后在你的组件更新时滚动到它。
return (
<div
className="messagesWrapper"
style={{ background: "white", border: "2px red solid" }}
>
{messages.map((message) => (
<span key={message}>{message}</span>
))}
<div ref={dummy} />
</div>
);
ref 元素在 useEffect 中更新。
const dummy = useRef(null);
useEffect(() => {
dummy.current.scrollIntoView({ behavior: "smooth" });
}, [messages]);
附上一张sandbox供参考。
所以您可以做的是创建一个 useRef,然后将其初始化为 null
然后当您在数组上映射以呈现对象时,运行 一个函数来检查它是否是数组中的最后一项
如果它是数组中的最后一个对象,则将 ref 附加到它
然后使用依赖数组中的 ref 进行 useEffect
如果 useRef 设置了一个新值,从 .map,在你的 useEffect 中,有一个 scrollTo 行为,平滑的,滚动到它的功能
我认为这会起作用:
React.useEffect(() => {
dummy.current.scrollTop = dummy.current.scrollHeight
})
我有一个 Message
组件,它在一个线程中显示所有消息(传入和传出)。
我希望最后 message/a 条新输入的 message/incoming 消息始终显示在对话的底部。有点像所有 chats/messaging 应用程序所做的。
这是我的代码:
import React, { useRef } from "react";
const dummy = useRef();
...
dummy?.current?.scrollIntoView(true, {
behaviour: "auto",
});
...
<div className="">
<Paper
elevation={0}
sx={{
backgroundColor: "#fafafa",
maxHeight: 200,
overflow: "auto",
}}
>
{messages.map((message, idx) => (
<div key={idx} ref={dummy}>
<Message message={message} name={name} />
</div>
))}
{/* I tried this also
<div ref={dummy}></div> */}
</Paper>
</div>
我希望当我单击 conversation/thread 时,所有可以放入带有 maxHeight: 200
的父 div 的消息,最后一条消息显示在底部。目前,整个页面滚动到底部,而不仅仅是线程中的消息。页面应保持静止。
我该怎么做?
问题是您将 ref
传递给呈现 Message
组件的 div
元素。我建议你在聊天结束时使用虚拟 div
,然后在你的组件更新时滚动到它。
return (
<div
className="messagesWrapper"
style={{ background: "white", border: "2px red solid" }}
>
{messages.map((message) => (
<span key={message}>{message}</span>
))}
<div ref={dummy} />
</div>
);
ref 元素在 useEffect 中更新。
const dummy = useRef(null);
useEffect(() => {
dummy.current.scrollIntoView({ behavior: "smooth" });
}, [messages]);
附上一张sandbox供参考。
所以您可以做的是创建一个 useRef,然后将其初始化为 null
然后当您在数组上映射以呈现对象时,运行 一个函数来检查它是否是数组中的最后一项
如果它是数组中的最后一个对象,则将 ref 附加到它
然后使用依赖数组中的 ref 进行 useEffect
如果 useRef 设置了一个新值,从 .map,在你的 useEffect 中,有一个 scrollTo 行为,平滑的,滚动到它的功能
我认为这会起作用:
React.useEffect(() => {
dummy.current.scrollTop = dummy.current.scrollHeight
})