You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在每次调用updateExpense()后触发setExpenses()更新费用数组?

问题解决思路

1. 修复updateExpense函数的response未定义问题

当前代码中console.log('Server response:', response.data);里的response未声明,会导致代码报错并中断后续dispatch执行,这是状态不更新的核心原因之一,修正后代码:

async function updateExpense(_id, expenseData) {
    try {
        const response = await axios.put(`http://localhost:8082/expenses2/${_id}`, expenseData);
        console.log('Server response:', response.data);
        dispatch({ type: 'UPDATE', payload: { _id, expenseData } })
    } catch (error) {
        console.error('Error updating expense:', error);
    }
}

2. 修正Reducer中UPDATE分支的payload取值错误

Reducer里尝试读取action.payload.data,但dispatch时传入的参数是expenseData,两者不匹配导致更新失效,修正后代码:

case 'UPDATE':
    const updatableExpenseIndex = state.findIndex((expense) => expense._id === action.payload._id)
    const updatableExpense = state[updatableExpenseIndex]
    const updatedItem = { ...updatableExpense, ...action.payload.expenseData }
    const updatedExpenses = [...state]
    updatedExpenses[updatableExpenseIndex] = updatedItem
    return updatedExpenses

3. 调整初始数据加载的useEffect依赖

原useEffect依赖数组为空,仅在组件挂载时执行一次,若useFetchExpenses返回的expenses是异步加载的(初始为undefined,后续才获取到数据),会错过状态更新时机,需添加expenses到依赖数组:

useEffect(() => {
    if (expenses) {
        setExpenses(expenses);
    }
}, [expenses]);

4. 确认Context状态映射正确性

确保ExpensesContext提供的expenses是reducer管理的expensesState,而非其他未更新的变量:

function ExpensesContextProvider({ children }) {
    const [expensesState, dispatch] = useReducer(expensesReducer, []);
    const { expenses, loading, error } = useFetchExpenses();

    useEffect(() => {
        if (expenses) {
            dispatch({ type: 'SET', payload: expenses });
        }
    }, [expenses]);

    async function updateExpense(_id, expenseData) {
        // 修复后的updateExpense逻辑
    }

    return (
        <ExpensesContext.Provider
            value={{
                expenses: expensesState,
                updateExpense,
                // 其他上下文属性
            }}
        >
            {children}
        </ExpensesContext.Provider>
    );
}

5. 移除冗余的setExpenses调用

在ManageExpense.js的confirmHandler中,无需额外调用expensesCtx.setExpenses()——修复完成后,updateExpense内的dispatch会自动更新reducer状态,触发组件重新渲染。

内容的提问来源于stack exchange,提问作者codereyes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 15:26:02