Попытка преобразовать демонстрационный ChatApp с помощью Socket.io из компонента класса в функциональный компонент с использованием реакционных хуков. Я хотел бы сохранить имя пользователя, экземпляр сокета, содержимое чата и журнал предыдущих сообщений, используя состояние между рендерами, чтобы клиент не подключался снова и снова с другим Socket.id или пытался печатать без текста. .
Моя проблема в том, что когда я пытаюсь использовать useEffect
как componentWillMount
, кажется, что он вообще не может сохранить экземпляр socket.io или изменить его состояние, не сделав его непригодным для использования:
Пример:
function myComponent() {
const [socket, setSocket] = useState("none");
useEffect(() => {
setSocket(io('http://127.0.0.1:1000'));
//but _socket_ is still "none" at this point unfortunately
socket.on('connection', () => {
setUsername(socket.id.slice(0, 3))
})
}, [])
//...
В настоящее время код также выполняется в бесконечном l oop, что меньше, чем желательно.
Как сохранить данные между рендерами и только один раз открывать сокеты с крючками?
import React, { useEffect, useState } from 'react'
import Footer from './Footer';
import io from "socket.io-client"
const endpoint = "http://192.168.254.22:1000"
function ChatApp() {
const [socket, setSocket] = useState("Loading");
const [username, setUsername] = useState("");
const [futureMessage, setFutureMessage] = useState("");
const [messageLog, setMessageLog] = useState([]);
function initSocket() {
const new_socket = io(endpoint); //open socket on the URL of our server
new_socket.on('connect', () => {
setSocket(new_socket);
setUsername(new_socket.id.slice(0,3));//first 3 letters of socket ID
})
new_socket.on('NEW_MESSAGE', (incoming_username, incoming_message) => {
let newMessage = <p key={this.state.all_messages.length}><b>{incoming_username}</b>: {incoming_message}</p>;
setMessageLog(messageLog.push(newMessage));
})
}
useEffect( ()=> {
initSocket();
});
function handleChange(e) {
setFutureMessage(e.target.value);
}
function handleSubmit(e) {
e.preventDefault();
socket.emit("NEW_MESSAGE_TO_SERVER", username, futureMessage);
setFutureMessage(""); //reset message box
}
return (
<div className="standard-window" id="chat-window">
<div className = "chat-window-title">
<h1>Test Chat App</h1>
<p>{socket ? ("Socket ID: " + socket.id):null}</p>
</div>
{/*------------------------------------*/}
<div className = "chat-window-messages">
{messageLog}
</div>
{/*------------------------------------*/}
<div className = "chat-window-input">
<form onSubmit = {handleSubmit}>
<input
type="text"
id="message-text-input-field"
placeholder="Type your message here..."
onChange={handleChange}
value={futureMessage}
/>
</form>
</div>
{/*------------------------------------*/}
<Footer />
</div>
)
};
export default ChatApp