Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

233
Vistas
Can't use react state inside a socketio on event callback function

I am trying to make a component where when you add a task, an event listener gets added to the socketio client. The event gets triggered when the server reports the progress of the task and I want to update the task with the new progress.

The problem is that when I update the task progress, the event callback function uses the state of the component when the function got assigned. If the "tasks" state was empty prior to assignment, the progress update erases the state.

I don't know how I can use the current state inside the callback function. (The progress update does work outside of the event callback)

Here is a minimal reproducible example:

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>
    );
}
about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

You have to use the setter with callback, in order to get the current value of the 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);
    })
}
about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda