skip to Main Content

The problem is that the expenses array is not being updated after submitting the updated expense and that is what’s providing expenses throughout the app.

In order to reflect the updates I have to reload the app (so the useEffect hook can set the expenses array) or submit another expense to see the changes reflected.

When I first load the mobile app I call setExpenses in my ExpensesContextProvider to load expenses from mongodb into the expenses array:

export const ExpensesContext = createContext({
    expenses: [],
    ...
    })

useFetchExpenses() hook fetches expenses from mongodb. The useEffect hook sets expenses to the expenses array.

function ExpensesContextProvider({ children }) {
    const [expensesState, dispatch] = useReducer(expensesReducer, []);
    // Fetch expenses using the custom hook
    const { expenses, loading, error } = useFetchExpenses();

    // Call setExpenses when expenses are fetched successfully
    useEffect(() => {
        if (expenses) {
            setExpenses(expenses);
        }
    }, []);

In the updateExpense function:

async function updateExpense(_id, expenseData) {
    try {
        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);
    }
}

I’m dispatching ‘UPDATE’:

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

In the ManageExpense.js file I call updateExpense in the confirm handler. I tried adding a call to expensesCtx.setExpenses() after calling expensesCtx.updateExpense but I still have to reload the app to get the latest data.

function confirmHandler(expenseData) {
        if (isEditing) {
            expensesCtx.updateExpense(_id, expenseData)
            // expensesCtx.setExpenses()

If you have any ideas i’d love to hear them 🙂

2

Answers


  1. Chosen as BEST ANSWER

    I solved this by adding async await syntax to the confirm handler:

    async function confirmHandler(expenseData) {
        if (isEditing) {
            expensesCtx.updateExpense(_id, expenseData)
            await expensesCtx.setExpenses()
    

    The expenses are now showing latest data after an expenses add/update is submitted.


  2. if you want to call setExpenses(expenses) whenever value of expenses changes then, you have to pass it as the dependency to the useEffect like below

    // Call setExpenses when expenses get updated
    useEffect(() => {
        if (expenses) {
            setExpenses(expenses);
        }
    }, [expenses]);  // pass to the dependency array
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search