I'm going crazy. I really don't understand why the below is not working. I'm starting with react. I'm trying to fetch datas from server and load my state before rendering. Socket "fromAPI" is ok, this is only a timer. Socket "lobbyUpdate " not working , i'm fetching data from database.
import React, { useState, useEffect } from "react";
import socketIOClient from "socket.io-client";
const ENDPOINT = "http://localhost:2500";
function Lobby() {
const [response, setResponse] = useState("")
const [updates, setUpdates] = useState([])
useEffect(() => {
const socket = socketIOClient(ENDPOINT);
socket.on("FromAPI", data => {
setResponse(data);
});
socket.on('lobbyUpdate', datas => {
console.log(updates) // Nothing
setUpdates(datas)
console.log(datas) // datas are displayed
console.log(updates) // nothing is displayed
})
// CLEAN UP THE EFFECT
return () => socket.disconnect();
//
}, []);
Please can you help me ? i didn't find similar case . Thanks.
Your updates
inside the useEffect
is referencing the value from the initial render, rather than the value currently being rendered. To fix it, either use refs instead of (or in addition to) state, or have the useEffect
run every time the updates change:
function Lobby() {
const [response, setResponse] = useState("")
const [updates, setUpdates] = useState([])
const socketRef = useRef();
// Create the socket
// and add the API listener:
useEffect(() => {
socketRef.current = socketIOClient(ENDPOINT);
socketRef.current.on("FromAPI", setResponse);
return () => socketRef.current.disconnect();
}, []);
useEffect(() => {
const handleLobbyUpdate = (datas) => {
console.log(updates); // this will now display the current data
setUpdates(datas);
};
socketRef.current.on('lobbyUpdate', handleLobbyUpdate);
return () => {
socketRef.current.off('lobbyUpdate', handleLobbyUpdate);
}
}, [updates]);
Remember that state setters are asynchronous, so you won't see a change in the updates
variable immediately after calling setUpdates
- you'll have to wait until the next render for the updates
to become populated.