Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

231
Visualizações
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 Respostas
Responde à pergunta

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda