如何立即更新 React setState

时间:2021-05-30 13:04:01

标签: reactjs asynchronous state use-effect setstate

我在“onClick”事件上调用 AddItemToList()。 然而,由于 setTotalExpensesAmount() 是异步的,它被调用得太晚了,而且 axios.post() 将错误的 totalExpenses 值发送到数据库(前一个)。

我相信,在 AddItemToList() 函数之外使用 useEffect() 不是一个正确的解决方案。

我应该让 axios.post() 成为 setTotalExpensesAmount() 的回调吗?如果是这样,我该怎么做?

const AddItemToList = () => {
        if (Expense !== '' && Amount !== '' && Number(Amount) > 0) {
            setExpenseAndAmountList(
                [
                    ...expenseAndAmountList, 
                    { 
                        expenseTitle: Expense,
                        expenseAmount: Amount,
                        id: Math.random() * 1000
                    }
                ]
            );

            axios.post('http://localhost:4000/app/insertedExpenseAndAmount', 
            {
                expenseTitle: Expense,
                expenseAmount: Amount
            });
            
            setTotalExpensesAmount((currentTotalExpenses: number) => currentTotalExpenses + Number(Amount));

            axios.post('http://localhost:4000/app/totalexpensesamount', 
            {
                totalExpensesAmount: totalExpenses
            });
            
            setExpense("");
            setAmount("");
            setIfNotValidInputs(false);
            setTotalBalance(Number(income) - totalExpenses);
        } else {
            setIfNotValidInputs(true);
        }
    }

1 个答案:

答案 0 :(得分:0)

有两种方法可以做到这一点。

  1. 您可以计算 newTotalExpense 并使用新值执行 setTotalExpense。此外,在您进行的帖子调用中传递 newTotalExpense
    const AddItemToList = () => {
        if (Expense !== '' && Amount !== '' && Number(Amount) > 0) {
            setExpenseAndAmountList(
                [
                    ...expenseAndAmountList, 
                    { 
                        expenseTitle: Expense,
                        expenseAmount: Amount,
                        id: Math.random() * 1000
                    }
                ]
            );

            axios.post('http://localhost:4000/app/insertedExpenseAndAmount', 
            {
                expenseTitle: Expense,
                expenseAmount: Amount
            });

            const newTotalExpense = currentTotalExpenses + Number(Amount)
            setTotalExpensesAmount(newTotalExpense);

            axios.post('http://localhost:4000/app/totalexpensesamount', 
            {
                totalExpensesAmount: newTotalExpense
            });
            
            setExpense("");
            setAmount("");
            setIfNotValidInputs(false);
            setTotalBalance(Number(income) - totalExpenses);
        } else {
            setIfNotValidInputs(true);
        }
    }
  1. 您可以使用 useEffect 钩子,它会在 totalExpense 值更改时触发。您可以在 useEffect 内进行 post 调用。
    useEffect(() => {
        axios.post('http://localhost:4000/app/totalexpensesamount', 
        {
            totalExpensesAmount: totalExpenses
        });        
    }, [totalExpense])
    
    const AddItemToList = () => {
        if (Expense !== '' && Amount !== '' && Number(Amount) > 0) {
            setExpenseAndAmountList(
                [
                    ...expenseAndAmountList, 
                    { 
                        expenseTitle: Expense,
                        expenseAmount: Amount,
                        id: Math.random() * 1000
                    }
                ]
            );

            axios.post('http://localhost:4000/app/insertedExpenseAndAmount', 
            {
                expenseTitle: Expense,
                expenseAmount: Amount
            });
            
            setTotalExpensesAmount((currentTotalExpenses: number) => currentTotalExpenses + Number(Amount));

            setExpense("");
            setAmount("");
            setIfNotValidInputs(false);
            setTotalBalance(Number(income) - totalExpenses);
        } else {
            setIfNotValidInputs(true);
        }
    }