Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

231
Visualizações
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 Respostas
Responde à pergunta

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda