Привет. Я столкнулся с проблемой использования хуков и socket.io. У меня нет опыта и горят сроки, поэтому прошу компетентного мнения. Прежде чем описать проблему (я знаю, что проблем там гораздо больше и только буду рад рекомендациям по устранению их, так как я осваиваюсь в MERN), хочу рассказать о ситуации. Итак, на сервере сокет слушает сообщение "
connection" там же слушает специальное сообщение от клиента. Если оно приходит - достать из БД список пользователей и отправить клиенту. Что делает клиент, при первом рендере создается 1 функция в хуке callback, то есть она будет создана 1 раз, так как с пустыми депсами. Внутри коннект сокета и установка прилетевших данных с сервака. Теперь проблема: при первом отображении все океy, но при повторном рендере какая-то утечка происходит. Я предполагаю, что это связано с хуком useState, который я использую.
В общем код сервера:
io.sockets.on('connection', socket => {
console.log('socket connected id: ', socket.id)
socket.emit('connection', 'hello from server')
listenReqOnUsers(socket, 'getUserList', 'takeUserList') // Слушает запрос на выборку всех пользователей и отсылает
listenReqOnMessages(socket, 'giveMessageList', 'getMessageList')
socket.on('disconnect', () => {
console.log('user disconnected: ', socket.id);
})
})
Код слушателей на сервере:
const listenReqOnUsers = (socket, fromChannel, toChannel) => {
socket.on(fromChannel, async () => {
const dataUsers = await User.find()
socket.emit(toChannel, dataUsers)
})
}
const listenReqOnMessages = (socket, fromChannel, toChannel) => {
socket.on(fromChannel, async () => {
const dataUsers = await Message.find()
socket.emit(toChannel, dataUsers)
})
}
И проблемный клиент:
import React, { useCallback, useEffect, useState, useRef} from 'react'
import {Link} from 'react-router-dom'
import DialogUser from './DialogUser'
import socket from '../socket'
const UsersList = () => {
const [usrs, setUsrs] = useState(null)
const usrsRef = useRef()
const [mes, setMes] = useState(false)
usrsRef.current = usrs
const getUsrs = useCallback(() => {
socket.emit('getUserList')
socket.on('takeUserList', dataUsers => {
console.log('Подключился к прослушиванию сообщений в user list с id: ', socket.id)
setUsrs(dataUsers)
})
}, [])
useEffect(() => {
getUsrs()
}, [])
useEffect(() => {
console.log('обновилось: ', usrsRef.current)
}, [usrsRef.current])
return (
<div>
{console.log('users: ', usrsRef.current)}
<div style={{maxHeight: '150px', height:'150px', overflowY: 'scroll'}}>
<div>
{usrsRef.current !== null && usrsRef.current !== undefined && usrsRef.current.map((usr, index) => <div key = {index}>
{`usr email: ${usr.email}`}
<Link to="#" /*onClick = {() => {setMes(!mes)}}*/ className="btn-floating btn-large waves-effect waves-light red"><i className="material-icons">mail</i></Link>
{/* <button onClick = {() => setMes(!mes)}/> */}
</div>)}
</div>
</div>
{/* {mes && <DialogUser/>} */}
</div>
)
}
export default UsersList
Скрин: