Как получать события SocketIO в React при использовании состояний

Это часть моего кода, что я хочу сделать, так это то, что этот компонент в любое время может получить сообщение в любом из разговоров. Отправка сообщения вызывает событие 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);
    });
  }, []);
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
278
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Хотя подключение и удаление прослушивателей сокетов каждый раз при изменении 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

Другие вопросы по теме