使用 React 发送消息时聊天滚动到底部
Chat scroll to bottom when send a message using React
我希望聊天 window 在我发送文本时向下滚动。
实际上发送的消息不会触发滚动,所以它们被隐藏了。
这是一个 example ( I'm using the chat component of MS Fluent UI for React library )
我找到了这个 但我无法集成它(不知道在哪里声明了 endMessage )在我的例子中它的值是 undefined
.
import React from "react";
import { Avatar, Chat, Divider, Input } from "@fluentui/react-northstar";
import { AcceptIcon } from "@fluentui/react-icons-northstar";
const janeAvatar = {
image: "public/images/avatar/small/ade.jpg",
status: {
color: "green",
icon: <AcceptIcon />
}
};
const ChatExample = () => {
const items = [
{
message: (
<Chat.Message
content="Hello"
author="John Doe"
timestamp="Yesterday, 10:15 PM"
mine
/>
),
contentPosition: "end",
attached: "top",
key: "message-id-1"
},
{
message: (
<Chat.Message
content="I'm back!"
author="John Doe"
timestamp="Yesterday, 10:15 PM"
mine
/>
),
contentPosition: "end",
attached: true,
key: "message-id-2"
},
{
message: (
<Chat.Message
content={{
content: (
<div>
What do you think about <a href="#">www.goodFood.com</a>?
</div>
)
}}
author="John Doe"
timestamp="Yesterday, 10:15 PM"
mine
/>
),
contentPosition: "end",
attached: "bottom",
key: "message-id-3"
},
{
gutter: <Avatar {...janeAvatar} />,
message: (
<Chat.Message
content="Hi"
author="Jane Doe"
timestamp="Yesterday, 10:15 PM"
/>
),
attached: "top",
key: "message-id-4"
},
{
gutter: <Avatar {...janeAvatar} />,
message: (
<Chat.Message
content="Looks good!"
author="Jane Doe"
timestamp="Yesterday, 10:15 PM"
/>
),
attached: true,
key: "message-id-5"
},
{
gutter: <Avatar {...janeAvatar} />,
message: (
<Chat.Message
content={
<div>
I also like <a href="#">www.goodFood2.com</a>.
</div>
}
author="Jane Doe"
timestamp="Yesterday, 10:15 PM"
/>
),
attached: "bottom",
key: "message-id-6"
},
{
message: (
<Chat.Message
content="Would you like to grab lunch there?"
author="John Doe"
timestamp="Yesterday, 10:16 PM"
mine
/>
),
contentPosition: "end",
key: "message-id-7"
},
{
gutter: <Avatar {...janeAvatar} />,
message: (
<Chat.Message
content="Sure! Let's try it."
author="Jane Doe"
timestamp="Yesterday, 10:15 PM"
/>
),
key: "message-id-8"
},
{
children: <Divider content="Today" color="brand" important />,
key: "message-id-9"
},
{
message: (
<Chat.Message
content="Ok, let's go."
author="John Doe"
timestamp="Today, 11:15 PM"
mine
/>
),
contentPosition: "end",
key: "message-id-10"
}
];
const [inputValue, setInputValue] = React.useState("");
const [itemsChat, setItemsChat] = React.useState(items);
const chatStyle = {
height: 500,
overflow: "scroll"
};
const handleKeyDown = event => {
if (event.key == "Enter") {
console.log(event);
let elm = {
message: (
<Chat.Message
content={inputValue}
author="John Doe"
timestamp="Yesterday, 10:15 PM"
mine
/>
),
contentPosition: "end",
attached: "top",
key: "message-id-1"
};
setItemsChat(itemsChat => [...itemsChat, elm]);
setInputValue("");
}
};
return (
<div>
<Chat style={chatStyle} items={itemsChat} />
<Input
fluid
placeholder="Inverted color input..."
value={inputValue}
onKeyDown={event => handleKeyDown(event)}
onChange={event => setInputValue(event.target.value)}
/>
</div>
);
};
export default ChatExample;
endMessage 变量是对他们在聊天结束时包含的空 div 的引用。
您可以在 React 文档中了解有关 React 中 refs 的更多信息:https://reactjs.org/docs/refs-and-the-dom.html
另一个问题的示例代码的不同之处在于它们不使用内置的 createRef 方法,而是传递一个自定义函数,该函数将更新 .endMessage 变量以指向当前元素。
React 文档中显示的方法是在组件的顶部添加一个变量,并用 useRef 挂钩填充它(将其命名为 endMessage 以与另一个 post 的方案保持一致)
然后在 div 中作为最后一条聊天消息,您可以将该变量用于 ref 属性:
<div ref={endMessage} />
在成功新建 post 的回调函数中,您将调用 endMessage.current.scrollIntoView
(注意:使用内置的 React ref 钩子或函数时,必须使用 current。如果您通过ref 道具的自定义函数,您始终可以直接分配引用的当前部分,如其他 SO post.
所示
我不熟悉您正在使用的聊天组件,因此我无法就如何将 div 放在最底部提供任何提示。另一个问题是关于 generic/self-programmed 聊天工具,假设您可以控制聊天框,并可以在呈现动态聊天消息列表的末尾放置一个静态元素。
您可以简单地使用带有 itemsChat
的效果作为依赖。只需抓住聊天 ul
元素并滚动到底部。
useEffect(() => {
document.querySelector('.ui-chat').scrollTop = document.querySelector('.ui-chat').scrollHeight
}, [itemsChat])
我希望聊天 window 在我发送文本时向下滚动。
实际上发送的消息不会触发滚动,所以它们被隐藏了。
这是一个 example ( I'm using the chat component of MS Fluent UI for React library )
我找到了这个 undefined
.
import React from "react";
import { Avatar, Chat, Divider, Input } from "@fluentui/react-northstar";
import { AcceptIcon } from "@fluentui/react-icons-northstar";
const janeAvatar = {
image: "public/images/avatar/small/ade.jpg",
status: {
color: "green",
icon: <AcceptIcon />
}
};
const ChatExample = () => {
const items = [
{
message: (
<Chat.Message
content="Hello"
author="John Doe"
timestamp="Yesterday, 10:15 PM"
mine
/>
),
contentPosition: "end",
attached: "top",
key: "message-id-1"
},
{
message: (
<Chat.Message
content="I'm back!"
author="John Doe"
timestamp="Yesterday, 10:15 PM"
mine
/>
),
contentPosition: "end",
attached: true,
key: "message-id-2"
},
{
message: (
<Chat.Message
content={{
content: (
<div>
What do you think about <a href="#">www.goodFood.com</a>?
</div>
)
}}
author="John Doe"
timestamp="Yesterday, 10:15 PM"
mine
/>
),
contentPosition: "end",
attached: "bottom",
key: "message-id-3"
},
{
gutter: <Avatar {...janeAvatar} />,
message: (
<Chat.Message
content="Hi"
author="Jane Doe"
timestamp="Yesterday, 10:15 PM"
/>
),
attached: "top",
key: "message-id-4"
},
{
gutter: <Avatar {...janeAvatar} />,
message: (
<Chat.Message
content="Looks good!"
author="Jane Doe"
timestamp="Yesterday, 10:15 PM"
/>
),
attached: true,
key: "message-id-5"
},
{
gutter: <Avatar {...janeAvatar} />,
message: (
<Chat.Message
content={
<div>
I also like <a href="#">www.goodFood2.com</a>.
</div>
}
author="Jane Doe"
timestamp="Yesterday, 10:15 PM"
/>
),
attached: "bottom",
key: "message-id-6"
},
{
message: (
<Chat.Message
content="Would you like to grab lunch there?"
author="John Doe"
timestamp="Yesterday, 10:16 PM"
mine
/>
),
contentPosition: "end",
key: "message-id-7"
},
{
gutter: <Avatar {...janeAvatar} />,
message: (
<Chat.Message
content="Sure! Let's try it."
author="Jane Doe"
timestamp="Yesterday, 10:15 PM"
/>
),
key: "message-id-8"
},
{
children: <Divider content="Today" color="brand" important />,
key: "message-id-9"
},
{
message: (
<Chat.Message
content="Ok, let's go."
author="John Doe"
timestamp="Today, 11:15 PM"
mine
/>
),
contentPosition: "end",
key: "message-id-10"
}
];
const [inputValue, setInputValue] = React.useState("");
const [itemsChat, setItemsChat] = React.useState(items);
const chatStyle = {
height: 500,
overflow: "scroll"
};
const handleKeyDown = event => {
if (event.key == "Enter") {
console.log(event);
let elm = {
message: (
<Chat.Message
content={inputValue}
author="John Doe"
timestamp="Yesterday, 10:15 PM"
mine
/>
),
contentPosition: "end",
attached: "top",
key: "message-id-1"
};
setItemsChat(itemsChat => [...itemsChat, elm]);
setInputValue("");
}
};
return (
<div>
<Chat style={chatStyle} items={itemsChat} />
<Input
fluid
placeholder="Inverted color input..."
value={inputValue}
onKeyDown={event => handleKeyDown(event)}
onChange={event => setInputValue(event.target.value)}
/>
</div>
);
};
export default ChatExample;
endMessage 变量是对他们在聊天结束时包含的空 div 的引用。
您可以在 React 文档中了解有关 React 中 refs 的更多信息:https://reactjs.org/docs/refs-and-the-dom.html
另一个问题的示例代码的不同之处在于它们不使用内置的 createRef 方法,而是传递一个自定义函数,该函数将更新 .endMessage 变量以指向当前元素。
React 文档中显示的方法是在组件的顶部添加一个变量,并用 useRef 挂钩填充它(将其命名为 endMessage 以与另一个 post 的方案保持一致) 然后在 div 中作为最后一条聊天消息,您可以将该变量用于 ref 属性:
<div ref={endMessage} />
在成功新建 post 的回调函数中,您将调用 endMessage.current.scrollIntoView
(注意:使用内置的 React ref 钩子或函数时,必须使用 current。如果您通过ref 道具的自定义函数,您始终可以直接分配引用的当前部分,如其他 SO post.
我不熟悉您正在使用的聊天组件,因此我无法就如何将 div 放在最底部提供任何提示。另一个问题是关于 generic/self-programmed 聊天工具,假设您可以控制聊天框,并可以在呈现动态聊天消息列表的末尾放置一个静态元素。
您可以简单地使用带有 itemsChat
的效果作为依赖。只需抓住聊天 ul
元素并滚动到底部。
useEffect(() => {
document.querySelector('.ui-chat').scrollTop = document.querySelector('.ui-chat').scrollHeight
}, [itemsChat])