Escuché un evento en customhook y cuando ese evento funciona, tengo que hacer algo de lógica allí con el estado. Pero ahora solo obtengo una matriz vacía cada vez que funciona la devolución de llamada del evento.
const useChatHistoryList = () => { const sk = useSocket(); const [chatList, setChatList] = useState([]); const [end, setEnd] = useState(true); useEffect(() => { sk.emit('chatlist'); }, [start]); useEffect(() => { const onChatListReceived = data => { const _data = JSON.parse(data); setHistoryLoading(false); setChatList(_data); }; const onChatListToUpdateReceived = data => { const _data = JSON.parse(data); console.log(chatList);//getting only empty array everytime }; sk.on('chatlist', onChatListReceived); sk.on('chatlistToUpdate', onChatListToUpdateReceived); return () => { sk.off('chatlistToUpdate'); sk.off('chatlist'); }; }, []); return { chatList,end}; };Intente registrar sus datos primero para asegurarse de que los datos estén allí, luego configure su estado con los datos.
const [state, setState]= useState([]); const _onReceived = (data) => { // Here is your data from socket console.log(data); // Then set state value with data setState(data); } useEffect(()=>{ // Init socket listener socket.on("event", _onReceived); }, []); // This effect will runs everytime state value is set (including when setting default value) useEffect(()=>{ // Actual 'state' value console.log('State value: ', state); }, [state]);==========================
Editar, relacionado con sus códigos actualizados en la pregunta
Su función onChatListToUpdateReceived brinda un valor predeterminado vacío al oyente incluso más tarde cuando se actualiza, su oyente aún reconocerá el valor de chatList como una cadena vacía. Intente salir de onChatListToUpdateReceived fuera de useEffect.
const onChatListToUpdateReceived = data => { const _data = JSON.parse(data); console.log(chatList);//getting only empty array everytime }; useEffect(() => { const onChatListReceived = data => { const _data = JSON.parse(data); setHistoryLoading(false); setChatList(_data); }; sk.on('chatlistToUpdate', onChatListToUpdateReceived); return () => { sk.off('chatlistToUpdate'); sk.off('chatlist'); }; }, []); useEffect(() => { sk.off('chatlistToUpdate'); sk.on('chatlist', onChatListReceived); }, [chatList]);No he usado socket.io antes, pero esto es lo que quise decir con actualización asíncrona. A partir de su código, me pareció que su devolución de llamada está siendo llamada antes de que se actualice el estado. Entonces, para resolver esto, agregué useEffect() con chatList como una dependencia para que se llame a la devolución de llamada cada vez que se actualice chatList . Espero que esto tenga sentido.
const useChatHistoryList = () => { const sk = useSocket(); const [chatList, setChatList] = useState([]); const [end, setEnd] = useState(true); const onChatListReceived = data => { const _data = JSON.parse(data); setHistoryLoading(false); setChatList(_data); }; const onChatListToUpdateReceived = data => { const _data = JSON.parse(data); console.log(chatList); //getting only empty array everytime }; useEffect(() => { sk.on('chatlist', onChatListReceived); sk.on('chatlistToUpdate', onChatListToUpdateReceived); return () => { sk.off('chatlistToUpdate'); sk.off('chatlist'); }; }, []); // Emit chatlistToUpdate whenever chatList is updated useEffect(() => { sk.emit('chatlistToUpdate'); }, [chatList]); return { chatList, end }; };