繁体   English   中英

无法在事件回调函数的 socketio 中使用反应状态

[英]Can't use react state inside a socketio on event callback function

我正在尝试制作一个组件,当您添加任务时,会将事件侦听器添加到 socketio 客户端。 当服务器报告任务的进度并且我想用新的进度更新任务时触发该事件。

问题是当我更新任务进度时,事件回调函数在分配函数时使用组件的状态。 如果“任务”状态在分配之前为空,则进度更新会删除该状态。

我不知道如何在回调函数中使用当前状态。 (进度更新确实在事件回调之外起作用)

这是一个最小的可重现示例:

import React, {useEffect, useRef, useState} from "react";
import axios from "axios";
import socketIOClient from "socket.io-client"


export default function TestComponent() {
    const socketRef = useRef(null);
    const [tasks, setTasks] = useState([])  // task: {id, name, time_start, progress}

    useEffect(() => {
        if (socketRef.current == null) {
            socketRef.current = socketIOClient({path: "/api/socket.io"});
        }

        return () => {
            socketRef.current.disconnect();
        };
    }, []);

    function addTask(task) {
        setTasks([...tasks, task]);
        addTaskProgressEvent(task);
    }

    function addTaskProgressEvent(task) {
        const event = "task:" + task.id + ":progress";

        socketRef.current.on(event, (progress) => {
            // update task progress (this failes!)
            setTasks(tasks.map(list_task => list_task.id === task.id ?
                {...list_task, progress: progress} : list_task))

            console.log(progress);
        })
    }

    function handleStartTask() {
        axios.post("/api/task").then((response) => {
            addTask(response.data);
        });
    }

    return (
        <div className="TestComponent">
            <button onClick={handleStartTask}>
                start task
            </button>
        </div>
    );
}

您必须使用带有回调的 setter,才能获取 state 的当前值:

function addTaskProgressEvent(task) {
    const event = "task:" + task.id + ":progress";

    socketRef.current.on(event, (progress) => {
        // update task progress (this failes!)
        setTasks(oldTasks => oldTasks.map(list_task => list_task.id === task.id ?
            {...list_task, progress: progress} : list_task))

        console.log(progress);
    })
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM