Reactjs API调用后的套接字事件未在React应用程序中正确记录数据 应用程序

Reactjs API调用后的套接字事件未在React应用程序中正确记录数据 应用程序,reactjs,typescript,socket.io,Reactjs,Typescript,Socket.io,我正在开发这个应用程序,它从服务器加载数据,并将其显示在图表上,以仪表显示总数。当新数据存储在数据库上时,服务器也会发出一个事件。 在App.tsx中,我执行了一个API调用,并开始监听此事件 问题 API调用工作正常,加载并显示所有数据,问题出在socketio事件回调中。events数组为空,currentTotal为零,即初始值。我相信这个问题与useState钩子的错误使用有关,但我真的不知道如何用其他方法来解决 我曾尝试将socket.on()放在另一个useffect中,或者甚至放在

我正在开发这个应用程序,它从服务器加载数据,并将其显示在图表上,以仪表显示总数。当新数据存储在数据库上时,服务器也会发出一个事件。 在App.tsx中,我执行了一个API调用,并开始监听此事件

问题 API调用工作正常,加载并显示所有数据,问题出在socketio事件回调中。events数组为空,currentTotal为零,即初始值。我相信这个问题与useState钩子的错误使用有关,但我真的不知道如何用其他方法来解决

我曾尝试将socket.on()放在另一个useffect中,或者甚至放在useState钩子的同一个作用域中,但它只是创建了大量渲染,页面加载需要几秒钟的时间


这是我的App.tsx文件

...
    const [events, setEvents] = useState<Event[]>([])
    const [currentTotal, setCurrentTotal] = useState<number>(0)

    useEffect(() => {
        api
            .get('/events')
            .then((response) => {
                const total = totals(response.data)
                setCurrentTotal(total)
                setEvents(response.data)
            })
            .catch()

        socket.on('event-created', (newEvent: Event) => {
            if (newEvent.rule_name === 'entering') {
                newEvent.total = currentTotal + 1
            } else {
                newEvent.total = currentTotal - 1
            }

            setCurrentTotal(newEvent.total)
            setEvents([...events, newEvent])
        })
    })
...

尝试使用状态回调函数。通过这种方式可以获得当前值:

App.tsx

 setCurrentTotal((prev) => { 
   const val = newEvent.rule_name === 'entering' ? 1: -1;
   prev = prev + val:
   return prev;
 })
 setEvents((prev) => ([...prev, newEvent]))
 setCurrentTotal((prev) => { 
   const val = newEvent.rule_name === 'entering' ? 1: -1;
   prev = prev + val:
   return prev;
 })
 setEvents((prev) => ([...prev, newEvent]))