Answer the question
In order to leave comments, you need to log in
What may not be cleared subscriptions in useEffect?
Hello. I ran into a problem using hooks and socket.io. I have no experience and deadlines are burning, so I ask for a competent opinion. Before describing the problem (I know that there are many more problems there and I will only be glad for recommendations on how to eliminate them, since I am getting used to MERN), I want to talk about the situation. So, on the server, the socket is listening for the message " connection" listens to a special message from the client in the same place. If it comes, get the list of users from the database and send it to the client. What the client does is, at the first render, 1 function is created in the callback hook, that is, it will be created 1 time, since with empty deps. Inside the socket connection and setting the incoming data from the server.Now the problem is: on the first display everything is ok, but on re-render some kind of leak occurs.I assume that this is due to the useState hook that I use.In
general, the server code:
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
Answer the question
In order to leave comments, you need to log in
Read the doc
on
useEffect
https://reactjs.org/docs/hooks-reference.html#clea
... the component has been unmounted,
console.log('Подключился к прослушиванию сообщений в user list с id: ', socket.id)
setUsrs(dataUsers)
The answer helped, just in case it is:
useEffect(() => {
getUsrs()
return () => {
socket.offAny('takeUserList')
}
}, [])
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question