I am building a simple chat app with react, express and socket.io I got stuck on receiving message from backend server. Every time user receive some message, the useEffect
will runs approximately twice as much as before so after 5 or 6 received messages the app start really slow down.
useEffect(() => {
socket.on('mes', (data) => {
setChat([...chat, data]);
});
}, [chat]);
any idea how to make it run just once every time user receive a message?
Whole code
import Chat from '../Chat/chat';
import queryString from 'query-string';
let socket;
const ChatRoom = ({ location }) => {
const [name, setName] = useState('');
const [room, setRoom] = useState('');
const [message, setMessage] = useState('');
const [chat, setChat] = useState([]);
const ENDPOINT = 'http://localhost:4001/';
useEffect(() => {
const { name, room } = queryString.parse(location.search);
setName(name);
setRoom(room);
socket = socketIOClient(ENDPOINT);
socket.emit('join', { name, room });
return () => {
socket.emit('disconnect');
socket.disconnect();
};
}, [ENDPOINT, location.search]);
const click = (e) => {
e.preventDefault();
socket.emit('message', message);
setMessage('');
};
useEffect(() => {
socket.on('mes', (data) => {
setChat([...chat, data]);
});
}, [chat]);
return (
<div className="ChatRoom-Container">
{chat.map((mes, index) => {
return <Chat text={mes.text} user={mes.user} key={index}></Chat>;
})}
<input
value={message}
className="ChatRoom-Input"
onChange={(e) => setMessage(e.target.value)}
onKeyDown={(e) => {
return e.key === 'Enter' ? click(e) : null;
}}
></input>
</div>
);
};
export default ChatRoom;
Use setChat(prev => next)
instead of setChat(value)
so you don't have to reference the previous value from the closure:
useEffect(() => {
socket.on('mes', (data) => {
setChat(prev => [...prev, data]);
});
}, []);
useEffect(() => {
socket.on('mes', (data) => {
setChat([...chat, data]);
});
}, [chat]);
Here in your dependency array you have the chat variable as a dependency. According to rules when the value of chat changes the effect runs. as a result after you call setChat()
one time it changes the value of chat and as a result it runs the effect one more time. that's why your effect is being called twice.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.