如何立即更新 React setState

How to update React setState immediately

我在“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. 您可以计算 newTotalExpense 并使用新值执行 setTotalExpense。此外,在您正在进行的 post 调用中传递 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.
  2. 中调用 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);
        }
    }