【问题标题】:React useState value incorrect on socket.on在 socket.on 上反应 useState 值不正确
【发布时间】:2020-11-03 05:51:21
【问题描述】:

我是 socket.io 的新手,我正在尝试实现一个简单的通知。

我的问题是我执行handleClick 函数将open 转换为真值,而当socket.on 运行其读取错误/open 的默认值时。

Notification.js

const [open, setOpen] = useState(false);

const handleClick = (event) => {
    setAnchorEl(event.currentTarget);
    if (!open) {
        setOpen(true) // set open to true
    }
};

useEffect(() => {
    socket.on("notification", function (data) {
        console.log('SOCKET', open) // idk why this is reading false
    })
}, [])

编辑

这是我的use-case handleClick func 是用户加载他/她的通知的地方,它将设置open 为真,当socket 运行时,它将检查open 是否为真并将新通知发送到现有的通知数组

const handleClick = (event) => {
    setAnchorEl(event.currentTarget);
    if (!open) {
        setOpen(true) // set open to true
        dispatch(getNotifications(params)) // load user notifications
    }
};

useEffect(() => {
    socket.on("notification", function (data) {
        console.log('SOCKET', open) // returning false always
        notificationData(data.data)
    })
}, [])

const notificationData = ({ sender, message, notif }) => {
    setNotifCounter(notifCounter => notifCounter + 1)
    setNotification(_.startCase(sender) + ' - ' + message, 'info')
    if (open) { // check if user already loaded his/her own notification
        dispatch(getNewNotif(notif)) // push to array to avoid duplicate
    }
}

【问题讨论】:

    标签: javascript node.js reactjs websocket socket.io


    【解决方案1】:

    具有空依赖数组 ([]) 的效果只会在组件挂载时运行一次。相反,将open 添加到依赖数组中,以便在挂载时触发open 状态更新时的效果。问题是open的当前值被包含在socket.on回调中,所以当状态更新时回调需要重新包围open

    const [open, setOpen] = useState(false);
    
    const handleClick = (event) => {
        setAnchorEl(event.currentTarget);
        if (!open) {
            setOpen(true) // set open to true
        }
    };
    
    useEffect(() => {
        socket.on("notification", function (data) {
            console.log('SOCKET', open);
        })
    }, [open]) // <-- add open to effect dependency
    

    或者你可以在外部定义回调

    const [open, setOpen] = useState(false);
    
    const handleClick = (event) => {
        setAnchorEl(event.currentTarget);
        if (!open) {
            setOpen(true) // set open to true
        }
    };
    
    const socketOnHandler = data => console.log('SOCKET', open);
    
    useEffect(() => {
        socket.on("notification", socketOnHandler)  // <-- use callback
    }, [])
    

    【讨论】:

    • 我现在尝试了这个,它记录了 2x 1st log SOCKET false 2nd SOCKET true 现在向用户显示 2 倍的通知,只需要一次。
    • 我尝试了外部回调,但它仍然返回false
    • 似乎它正在接收一条消息,open 为假,一段时间后,在单击某些内容后收到第二条消息,open 现在为真。您能否提供更完整的组件代码和用例图片,即重现步骤?
    【解决方案2】:

    我不确定这是正确的方法。为了使它工作,当你将 socket.on 放入 useEffect 而不依赖时,它看起来解决了这个问题。

    useEffect(() => {
        socket.on("notification", function (data) {
            console.log('SOCKET', open) // idk why this is reading false
        })
    });
    

    还有一次,我不确定这种方式是否正确。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-10-28
      • 2021-10-05
      • 2021-08-05
      • 2020-07-19
      • 2021-09-06
      • 2018-07-27
      • 2021-12-15
      相关资源
      最近更新 更多