使用 socket.io 和反应挂钩时反应状态未更新

Recact state is not being updated when using socket.io and react hooks

我有如下组件。

import React,{useEffect,useState} from "react";
import {Marker} from "react-map-gl";
import io from "socket.io-client";
import { BASE_URL } from "../../../config/urls";
const socket = io(BASE_URL, {
    query: {
      token:
        "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXV",
    },
  });

export default function Route(){
    const [markerPos, setMarkerPos] = useState({
        longitude:8.5455940,latitude:47.3977421
    })
    const update=(data)=>{
        const obj = {
            longitude:data['gps.lon'],
            latitude:data['gps.lat']
        }
        setMarkerPos(prevProps =>{
            return {...prevProps,longitude:obj.longitude,latitude:obj.latitude}
        });
        console.log(markerPos.longitude,data['gps.lon'])
    }
    useEffect(()=>{
        socket.on("mission_data",(socketData)=>{
            update(socketData)
        })
    },[])

    return null;
}

在访问 Whosebug 上的一些问题时,我找到了这个解决方案。

问题:

Why is my state not being updated using React Hooks?
React State is not updated with socket.io

React State is not updated with socket.io

socket.on 仅被调用一次。 虽然,socketData 总是会更新。每次新数据来自 socket.io.

您可以在上图中看到,红色 颜色的右侧数据来自套接字并且正在更新。但是,绿色 颜色的左侧数据是反应状态变量未更新。

编辑

此问题与 不重复。

我知道反应异步更新状态。因此,状态更新不会立即反映。

在我的情况下,状态甚至没有更新,我等了一个小时。

markerPos 的状态是异步更新的。尝试渲染 MarkerPos,您应该会看到它发生了变化。如果你想在它改变时调用函数,使用另一个 useEffect hook

import React,{useEffect,useState} from "react";
import {Marker} from "react-map-gl";
import io from "socket.io-client";
import { BASE_URL } from "../../../config/urls";
const socket = io(BASE_URL, {
    query: {
      token:
        "xxxxxxx",
    },
  });

export default function Route(){
    const [markerPos, setMarkerPos] = useState({
        longitude:8.5455940,latitude:47.3977421
    })
    const update=(data)=>{
        const obj = {
            longitude:data['gps.lon'],
            latitude:data['gps.lat']
        }
        setMarkerPos(prevProps =>{
            return {...prevProps,longitude:obj.longitude,latitude:obj.latitude}
        });
        console.log(markerPos.longitude,data['gps.lon'])
    }
    useEffect(()=>{
        socket.on("mission_data",(socketData)=>{
            update(socketData)
        })
    },[])

    useEffect(()=>{
       console.log(markerPos)
    },[markerPos])
    return null;
}