Reactjs 从异步回调多次更新相同的状态

Reactjs 从异步回调多次更新相同的状态,reactjs,Reactjs,我正在尝试从并行启动的异步回调中更新相同的状态。问题是,每个异步回调都始终具有init状态,并且没有得到更新的状态。我已经尝试了一天不同的解决方案,但没有一个奏效。有没有办法做到这一点 代码示例: import React, { useState } from 'react'; import Button from '@material-ui/core/Button'; import http from '../../utils/clientHttp/clientHttp'; functio

我正在尝试从并行启动的异步回调中更新相同的状态。问题是,每个异步回调都始终具有init状态,并且没有得到更新的状态。我已经尝试了一天不同的解决方案,但没有一个奏效。有没有办法做到这一点

代码示例:

import React, { useState } from 'react';
import Button from '@material-ui/core/Button';
import http from '../../utils/clientHttp/clientHttp';


function Example() {
    const [calls, setCalls] = useState<string[]>([]);
    const [callsState, setCallsState] = useState<{[key:string]: string}>({ call1: 'init', call2: 'init', call3: 'init' });

    const onClick = () => {
        setCalls(['call1', 'call2', 'call3']);
        calls.forEach((call) => {
            http.post(call, '').then(() => {
                const copy = { ...callsState };
                copy[call] = 'done';
                setCallsState(copy);
            }).catch(() => {
                const copy = { ...callsState };
                copy[call] = 'error';
                setCallsState(copy);
            });
        });
    };

    return (
        <Button
            variant="contained"
            color="primary"
            onClick={onClick}
        >
            Try
        </Button>
    );
}

import React,{useState}来自“React”;
从“@material ui/core/Button”导入按钮;
从“../../utils/clientHttp/clientHttp”导入http;
函数示例(){
const[calls,setCalls]=useState([]);
const[callsState,setCallsState]=useState({call1:'init',call2:'init',call3:'init'});
const onClick=()=>{
setCalls(['call1','call2','call3']);
calls.forEach((call)=>{
http.post(调用“”)。然后(()=>{
const copy={…callsState};
复制[调用]=“完成”;
设置调用状态(副本);
}).catch(()=>{
const copy={…callsState};
复制[调用]=“错误”;
设置调用状态(副本);
});
});
};
返回(
尝试
);
}
它们都会转到错误和控制台日志:


您需要使用回调方法进行状态变异,以避免使用过时的对象

const onClick = () => {
    setCalls(['call1', 'call2', 'call3']);
    calls.forEach((call) => {
        http.post(call, '').then(() => {
            setCallsState(state => ({ ...state, [call]: 'done' }));
        }).catch(() => {
            setCallsState(state => ({ ...state, [call]: 'error' }));
        });
    });
};