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

225
Views
array of objects as props won't give me the proper values

I want to make a progress bar and I have two components. this is my chart component:

import Bar from "./Bar";

const INIT_MONTH_EXPENSES = [
  { label: "Jan", value: 0 },
  { label: "Feb", value: 0 },
  { label: "Mar", value: 0 },
  { label: "Apr", value: 0 },
  { label: "May", value: 0 },
  { label: "Jun", value: 0 },
  { label: "Jul", value: 0 },
  { label: "Aug", value: 0 },
  { label: "Sep", value: 0 },
  { label: "Oct", value: 0 },
  { label: "Nov", value: 0 },
  { label: "Dec", value: 0 },
];

const Chart = (props) => {
  const totalExpenseAmountOfYear = props.items.reduce((total, item) => {
    total = +total + +item.amount;
    return total;
  }, 0);

  for (const expense of props.items) {
    const expenseMonth = expense.date.getMonth();
    INIT_MONTH_EXPENSES[expenseMonth].value += expense.amount;
  }
  //INIT_MONTH_EXPENSES[2].value give me the expected value but props.expenses[2].value in the Bar component give me a wrong value(actually doubled value) 
  return (
    <div className="bg-pink-200 w-full h-[150px] p-4 mb-8 flex">
      <Bar
        expenses={INIT_MONTH_EXPENSES}
        totalAmount={totalExpenseAmountOfYear}
      />
    </div>
  );
};

export default Chart;

the problem is that when i log passed props "expenses" in the other component it give me wrong values . any help will be appreciated.

about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

When you pass an object declared in the parent component to the child component, in order for react to render the components again for the updated state you will have to use useState or useReducer hooks to notify the react engine that something has changed and I need you to re render the components again.

In the example you are just mutating the existing object and when you do that react has no idea that something has changed, so it ends up not rendering the child component with the updated data.

import Bar from "./Bar";
import { useState, useEffect } from 'react';

const INIT_MONTH_EXPENSES = [{
    label: "Jan",
    value: 0
  },
  {
    label: "Feb",
    value: 0
  },
  {
    label: "Mar",
    value: 0
  },
  {
    label: "Apr",
    value: 0
  },
  {
    label: "May",
    value: 0
  },
  {
    label: "Jun",
    value: 0
  },
  {
    label: "Jul",
    value: 0
  },
  {
    label: "Aug",
    value: 0
  },
  {
    label: "Sep",
    value: 0
  },
  {
    label: "Oct",
    value: 0
  },
  {
    label: "Nov",
    value: 0
  },
  {
    label: "Dec",
    value: 0
  },
];

const Chart = (props) => {
  // store the expenses in state so that it can be passed along.
  // only run the initializer when the component is mounted
  const [expenses, setExpenses] = useState(() => {
       return [...INIT_MONTH_EXPENSES];
  });
  const [totalExpenses, setTotalExpenses] = useState(0);
  
  const {
     items
  } = props;
  
  useEffect(() => {
     const updatedExpenses = items.reduce((memo, item) => {
        const expenseMonth = item.date.getMonth();
        
        if(memo[expenseMonth]) {
           memo[expenseMonth].value += expense.amount;
        }
        
        return memo;
     }, [...expenses]);
     
     // this will notify react that state changed and will re render the component
     setExpenses(updatedExpenses);
  }, [items]);
  
  // use effect to cal total expenses
  useEffect(() => {
     const totalExpenseAmountOfYear = items.reduce((total, item) => {
          total = +total + (+item.amount);
         
          return total;
     }, 0);
     
     setTotalExpenses(totalExpenseAmountOfYear);
  }, [items]);

  return ( <
    div className = "bg-pink-200 w-full h-[150px] p-4 mb-8 flex" >
    <
    Bar expenses = {
      expenses
    }
    totalAmount = {
      totalExpenses
    }
    /> <
    /div>
  );
};

export default Chart;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

Also need to make sure that setState is not called directly in the render. It should typically be called in useEffect, so you will have to figure out when the expenses need to be updated.

about 4 years ago · Juan Pablo Isaza 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!