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

时间:2020-09-02 08:03:31

标签: reactjs

我正在尝试从并行启动的异步回调中更新相同的状态。问题在于异步回调中的每一个总是具有初始化状态,而没有获得更新的状态。我一直在尝试不同的解决方案,但是没有一个奏效。有执行的方法吗?

代码示例:

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>
    );
}

所有这些都出错并且控制台日志:

enter image description here

1 个答案:

答案 0 :(得分:0)

您需要使用回调方法进行状态突变,以避免使用陈旧的对象

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