проблема с использованием socket.io с реакцией - PullRequest
1 голос
/ 23 января 2020

Я делаю socket.io с reactJS, пытаюсь отобразить новые сообщения, поступающие с сервера сокетов, useEffect вызывает код перед рендерингом, и это хорошо, но он останавливается на той строке, где должен работать useState, останавливается на эта строка и повторно RENDER DOM, а затем он вызывает useState. поэтому каждый раз, когда я получаю сообщение, ТОЛЬКО предыдущее сообщение появляется из-за этого раннего рендеринга, я помещаю код сокета за пределы useEffect, и он сходит с ума и продолжаю печатать сообщения

useEffect(()=>{

  getChatList();
  socket.emit("joinChatRoom",{chatRoomId:auth.userId});

  socket.on("messageToReciver",(data)=>{
    console.log("reciving message")
    console.log(data);
    arrayOfNewMessages.push((<MessageElement messages={[data]} senderId={data.reciverId} />));
  //at this point it re-render
  setNewMessages(arrayOfNewMessages);//here is the useState , but the code  stops here , it render the dom , then this line works, but this new message will only show up when the dom re-render again

    console.log(arrayOfNewMessages);
    })

},[])


console.log('re-render')
return (dom)

РЕДАКТИРОВАТЬ С НОВЫМ КОДОМ

  const [newMessages,setNewMessages] = useState([]);//this useState is Messages (the dom) 
  const [message,newMessage] = useState([]);//this one is messages (json data)

useEffect(()=>{

  getChatList();
  socket.emit("joinChatRoom",{chatRoomId:auth.userId});



},[])


useEffect(()=>{
  //it will run if message arrives and set our message to messages 
 if(message) {
    //here it's printing empty data when the app first lunch 
   console.log("not empty")
   arrayOfNewMessages.push((<MessageElement messages={[message]} senderId={message.reciverId} />));

    //at this point it re-render
    setNewMessages(arrayOfNewMessages);
} 

},[message])



   ////here it's consoling log the data 10 times 
  socket.on("messageToReciver",(data)=>{
    newMessage(data);

  console.log(data);
  })




//and here is the dom

returm(
 <div>
   {
     newMessages
   }
 </div>
)

1 Ответ

0 голосов
/ 23 января 2020

Вот мой компонент чата, проверьте это, это может быть полезно для вас

import React , { useState, useEffect } from 'react';
import queryString from 'query-string';
import './chat.css';
/* -------- Components ------- */
import TextContainer from '../TextContainer/TextContainer';
import Messages from '../Messages/Messages';
import InfoBar from '../InfoBar/InfoBar';
import Input from '../Input/Input';

//Socket.io
import io from 'socket.io-client';
let socket;


const Chat = ({location}) => {

    const [name,setName] = useState('');
    const [group,setGroup] = useState(''); 
    const [users,setUsers] = useState(''); 
    const [message,setMessage] = useState(''); 
    const [messages,setMessages] = useState([]); 

    const ENDPOINT = 'localhost:3030';

    useEffect(()=>{

        const {name , group} = queryString.parse(location.search);
        setName(name);
        setGroup(group);
        socket = io(ENDPOINT); //we are assigning our socket using endpoint

        //now we can use our socket with emit
        socket.emit('join',{ name , group},()=>{});

        return () => {
            socket.emit('disconnect')
            socket.off();
        }

    },[ENDPOINT,location.search])

    useEffect(()=>{
        socket.on('message',(message)=>{
            setMessages([...messages,message]);
        })
    },[messages])

    useEffect(()=>{
        socket.on('groupData',({users})=>{
            setUsers(users);
        })
    },[users])


    //function for sending messages 

    const sendMessage = (event) => {
        event.preventDefault();
        if(message){
            socket.emit('sendMessage', message , ()=> setMessage(''))
        }
    }

    return(
    <div className="outerContainer">
        <div className="container">
            <InfoBar group={group} />
            <Messages messages={messages} name={name} />
            <Input message={message} setMessage={setMessage} sendMessage={sendMessage} />
        </div>
        <TextContainer users={users}/>
    </div>
    )
}

export default Chat;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...