Это часть моего кода, что я хочу сделать, так это то, что этот компонент в любое время может получить сообщение в любом из разговоров. Отправка сообщения вызывает событие Socket, которое запускает этот код ниже, но я не могу получить «последние» разговоры, так как useEffect срабатывает только при монтировании компонента (в этот момент массив моих разговоров имеет нулевую длину).
Я думал, что мне следует включить «разговоры» о зависимости useEffect, но это создаст несколько подключений к веб-сокетам, по одному каждый раз, когда запускается событие Socket.io, потому что оно меняет состояние. Это лучшее решение? Заранее спасибо!
const [conversations, setConversations] = useState<Array<Conversations>>([]);
useEffect(() => {
async function getConversations() {
try {
const { data } = await axios.get("/api/conversations/");
if (data.success) {
setConversations(data.details);
}
} catch (err) {}
}
getConversations();
socketInstance.on("connect", () => {
console.info("Connecting to Sockets...");
socketInstance.emit("authenticate", Cookies.get("token") || "");
});
socketInstance.on("ackAuth", ({ success }) => {
console.info(
success
? "Successfully connected to Sockets"
: "There has been an error connecting to Sockets"
);
});
socketInstance.on("newMessage", (data) => {
const modifiedConversation: Conversations = conversations.find(
(conv: Conversations) => {
return conv.conversationId === data.conversationId;
}
);
modifiedConversation.messages.push({
from: {
firstName: data.firstName,
lastName: data.lastName,
profilePhoto: data.profilePhoto,
userId: data.userId,
},
content: data.content,
timeStamp: data.timeStamp,
});
const updatedConversations = [
...conversations.filter(
(conv) => conv.conversationId !== data.conversationId
),
modifiedConversation,
];
setConversations(updatedConversations);
});
}, []);
Хотя подключение и удаление прослушивателей сокетов каждый раз при изменении conversations
возможно, лучшим вариантом будет использование формы обратного вызова сеттеров. К счастью, единственный раз, когда вы ссылаетесь на состояние, вы переходите к его обновлению. Ты можешь измениться
socketInstance.on("newMessage", (data) => {
const modifiedConversation: Conversations = conversations.find(
// lots of code
setConversations(updatedConversations);
к
socketInstance.on("newMessage", (data) => {
setConversations(conversations => {
const modifiedConversation: Conversations = conversations.find(
// lots of code
setConversations(updatedConversations);
Вы также не должны мутировать состояние, так как это React. Вместо
modifiedConversation.messages.push({
делать
const modifiedConversationWithNewMessage = {
...modifiedConversation,
messages: [
...modifiedConversation.messages,
{
from: {
// rest of the object to add