猿问

与 socket io 结合使用时,React Hook(usestate)不起作用

我要疯了。我真的不明白为什么下面的不起作用。我从反应开始。我正在尝试从服务器获取数据并在渲染之前加载我的状态。套接字“fromAPI”没问题,这只是一个计时器。套接字“lobbyUpdate”不工作,我正在从数据库中获取数据。


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();

        //

      }, []);

你能帮帮我吗?我没有找到类似的案例。谢谢。


慕妹3242003
浏览 236回答 3
3回答

犯罪嫌疑人X

您的updates内部正在引用初始 renderuseEffect的值,而不是当前正在呈现的值。要修复它,要么使用 refs 而不是(或除了)state,或者在每次更新更改时运行:useEffectfunction 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]);请记住,状态设置器是异步的,因此您不会updates在调用后立即看到变量发生变化setUpdates- 您必须等到下一次渲染才能updates填充。

UYOU

您的代码运行良好,您只是将日志语句放在它们无用的地方。updates是局部常量。它永远不会改变,这不是我们setUpdates想要做的。useEffect 中的 console.log 语句只会引用第一次渲染时的response值。updates当您调用时setUpdates,您要求做出反应以重新呈现组件。在那个新渲染器上,将创建一个新的局部常量,并将获得新值。新渲染中的代码可以使用这个值,但以前渲染中的代码不能。如果您想验证它是否正在使用新值重新呈现,请将您的日志语句放入组件的主体中:function Lobby() {    const [response, setResponse] = useState("")    const [updates, setUpdates] = useState([])    console.log("rendering with: ", response, updates);    useEffect(() => {        const socket = socketIOClient(ENDPOINT);        socket.on("FromAPI", data => {          setResponse(data);        });        socket.on('lobbyUpdate', datas => {           setUpdates(datas)        })               // CLEAN UP THE EFFECT        return () => socket.disconnect();    }, []);

白猪掌柜的

您必须在 useEffect() 中定义套接字常量,它将在每次套接字更新后呈现 useEffect 挂钩。const [update,setupdate] = useState()useEffect(()=>{ const socket = io("http://localhost:3001");socket.on("send data", function (data_from_socket) { setupdate(data_from_socket);})})并且不要忘记不要在 useEfect 中使用 []
随时随地看视频慕课网APP

相关分类

JavaScript
我要回答