我正在使用 React JS(带有 chakra-ui 和 @chatscope/chat-ui-kit-react)和 Moralis Web3 创建一个我想要的聊天应用程序:
- 首次加载组件时获取所有消息,并且
- 每当表中添加新消息时订阅消息。这是使用 Moralis 提供的 websocket。
我能够在第一次使用useEffect
. 我将它存储在一个状态变量textMsgs
中。
问题是当我订阅时,在
subscription.on("create", (object) => {
console.log(textMsgs);
});
console.log 结果始终为空。而它应该显示我最初获取的最后一个数组。
然后我添加一个
<Button onClick={() => console.log(textMsgs)}>get textMsgs</Button>
检查 textMsgs 是否可以显示数组,并且它确实显示了数组。
我真的很困惑,为什么在subscription.on 中,textMsgs 是空的,但是当我单击按钮时,为什么它在加载组件时显示第一个获取?
完整代码:Messages.js
import { Container, Button, Text } from "@chakra-ui/react";
import Moralis from "moralis/dist/moralis.min.js";
import styles from "@chatscope/chat-ui-kit-styles/dist/default/styles.min.css";
import {
MainContainer,
ChatContainer,
MessageList,
Message,
MessageInput,
} from "@chatscope/chat-ui-kit-react";
import { useState, useEffect } from "react";
export const Messages = ({ roomId, userId }) => {
const [textMessage, setTextMessage] = useState("");
const [textMsgs, setTextMsgs] = useState("");
useEffect(() => {
getMessages();
subscribeMessages();
}, []);
const subscribeMessages = async () => {
const query = new Moralis.Query("Messages");
query.equalTo("roomId", roomId);
const subscription = await query.subscribe();
// on subscription object created
subscription.on("create", (object) => {
console.log(textMsgs);
});
};
// Get textMsgs in this room
const getMessages = async () => {
const Message = Moralis.Object.extend("Messages");
const message = new Moralis.Query(Message);
message.equalTo("roomId", roomId);
const msgResults = await message.find();
var msgs = [];
for (let i = 0; i < msgResults.length; i++) {
var username = await getUsername(msgResults[i].attributes.userId);
var msg = {
msgId: msgResults[i].id,
createdAt: msgResults[i].attributes.createdAt,
userId: msgResults[i].attributes.userId,
textMessage: msgResults[i].attributes.textMessage,
username: username,
};
msgs.push(msg);
}
setTextMsgs(msgs);
};
const getUsername = async (userId) => {
// Query username
const User = Moralis.Object.extend("User");
const user = new Moralis.Query(User);
user.equalTo("objectId", userId);
const userResults = await user.find();
return userResults[0].attributes.username;
};
const sendMessage = (e) => {
var newMsg = {
textMessage: textMessage,
userId: userId,
roomId: roomId,
};
const Message = Moralis.Object.extend("Messages");
const message = new Message();
message.set(newMsg);
message.save().then(
(msg) => {
// Execute any logic that should take place after the object is saved.
//alert("New object created with objectId: " + msg.id);
},
(error) => {
// Execute any logic that should take place if the save fails.
// error is a Moralis.Error with an error code and message.
alert("Failed to create new object, with error code: " + error.message);
}
);
};
return (
<Container>
{/* react chat */}
<div
style={{
height: "100vh",
}}
>
<Button onClick={() => console.log(textMsgs)}>get textMsgs</Button>
<MainContainer style={{ border: "0" }}>
<ChatContainer>
<MessageList>
<MessageList.Content>
{textMsgs &&
textMsgs.map((data, key) => {
return (
<div key={"0." + key}>
<Text
key={"1." + key}
align={data.userId === userId ? "right" : "left"}
fontSize="xs"
>
{data.username}
</Text>
<Message
model={{
message: data.textMessage,
direction:
data.userId === userId ? "outgoing" : "incoming",
sentTime: "just now",
sender: "Joe",
}}
key={"2." + key}
/>
</div>
);
})}
</MessageList.Content>
</MessageList>
<MessageInput
value={textMessage}
placeholder="Type message here"
attachButton={false}
onChange={(text) => {
setTextMessage(text);
}}
onSend={sendMessage}
/>
</ChatContainer>
</MainContainer>
</div>
</Container>
);
};
在这里您可以看到 Messages.js:30 (in subscription.on) 和 Messages.js:102 (in ) 显示不同的结果