Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

140
Views
React: Mapping an array of state objects does not show all state

I am having the following weird issue, using React. I am building a budget tracker app, which has a total budget, a form to add a new expense and in the end displays the expense with the cost bellow. The new cost is also subtracted from the total budget. I have the following states:

const [total, setTotal] = useState(1500);
const [expense, setExpense] = useState({
     name: "Expense",
     cost: "0"
   });
const [allExpenses, setAllExpenses] = useState([]);

The first one is the total budget. The second state - expense is the new expense, which is added from the form. allExpenses is an array of objects, which needs to be printed out bellow the form.

These are my setter methods, which occur onChange (in the input fields) and onSubmit (submitting the form):

const handleSubmit = event =>{
    event.preventDefault();
    let exp = expense.name;
    let cost = expense.cost;
    alert( "New expense " + exp + " costs " + cost );

    setTotal((prevTotal) => prevTotal - cost);

    const newAll = (prevAll) => ([...prevAll, expense]);
    setAllExpenses(newAll);
  }
  
  const handleChange = event =>{
     setExpense((prevExpense) => ({
     ...prevExpense, 
     [event.target.name]: event.target.value
      }))
  }

And in the render function, bellow the form, I call the array map() function to print out headers with the expense's name and cost.

{allExpenses.map(({item, cost}) => {return <h1>{item} costs {cost}$</h1>})}

I have also added a display component to track whether the state changes.

export function Printer (props){
    return(
        <h1>{props.name} costs {props.cost}$</h1> 
        /*
        Added as a change tracker. State DOES change.
        Issue is probably within the allExpenses state.
        
        */
    );
}

The problem is that the state does change. If I add a new expense - for example NewExpense, 12$, the printer component will display "NewExpense costs 12$". However, the mapping function of the array will display " costs 12$". The state has changed, but the expense.name attribute of the object doesn't show after mapping. Everything else seems to be working fine. I've tried rewriting the map() call and the setAllExpenses state setter. Nothing seems to be fixing the issue, which is quite peculiar. The form is also within the render (not in a separate component), so I am not passing any state through props. What am I missing here?

about 4 years ago · Santiago Gelvez
2 answers
Answer question

0

You need to make changes in array map function as below.

{allExpenses.map(({name, cost}) => {return <h1>{name} costs {cost}$</h1>})}

This should get print "NewExpense costs 12$".

about 4 years ago · Santiago Gelvez Report

0

You need to change the allExpenses state correctly.

Instead of this

const newAll = (prevAll) => ([...prevAll, expense]);
setAllExpenses(newAll);

Try this

setAllExpenses((prevAll) => [...prevAll, expense]);
about 4 years ago · Santiago Gelvez Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!