Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I re-render a component when an object is changed in React

I'm trying to build a simple expense log app in React and would like to display the latest data every time the expensesLog object is updated. On clicking the button, the clickHandler function is called and the object is updated but nothing seems to change on the UI inspite of me mapping the expenseLog object. Here's my code :

import './App.css';
import { useState } from 'react';

function App() {

  var expenseLog = [
    {
      name: "Expense1",
      amount: 1000
    },
    {
      name: "Expense2",
      amount: 100
    }
  ];

  var [count, setCount] = useState(0);
  var [name, setName] = useState("");

  const inputChangeHandler = (e) => { 
    setName(e.target.value);
  }

  const inputChangeHandler2 = (e) => { 
    setCount(e.target.value);
  }
  
  const clickHandler = () => { 
    expenseLog = [...expenseLog, {name: name, amount: count}];
    document.querySelector('.inputField').value = "";
    document.querySelector('.inputField2').value = 0;
  }

  return (
    <div className="App">
      <input onChange={inputChangeHandler} className='inputField'/>
      <input type={"number"} onChange={inputChangeHandler2} className='inputField2'/>
      <button onClick={clickHandler}></button>
      {expenseLog.map(expense => <p>{expense.name} {expense.amount}</p>)}
    </div>
  );
}

export default App;
like image 236
Vayun Avatar asked Oct 20 '25 17:10

Vayun


2 Answers

Your variable expenseLog is defined in the function body of your react component. That means react will initialize the variable on every render and thus forget all state that you mutated.

As you did with count and name, you need to wrap expensesLog into a React useState hook in order to maintain state inside your component.

like image 184
dominickque Avatar answered Oct 23 '25 06:10

dominickque


It's not updating UI as expenseLog is just object, and it's immutable when you don't change the reference.

So, you need to use expenseLog as State variable. And update it inside callback function using setExpenseLog for updating the state.

import "./App.css";
import { useState } from "react";

function App() {
  const [expenseLog, setExpenseLog] = useState([
    {
      name: "Expense1",
      amount: 1000,
    },
    {
      name: "Expense2",
      amount: 100,
    },
  ];)

  var [count, setCount] = useState(0);
  var [name, setName] = useState("");

  const inputChangeHandler = (e) => {
    setName(e.target.value);
  };

  const inputChangeHandler2 = (e) => {
    setCount(e.target.value);
  };

  const clickHandler = () => {
    setExpenseLog(prev => [...prev,{ name: name, amount: count } ])
    
    document.querySelector(".inputField").value = "";
    document.querySelector(".inputField2").value = 0;
  };

  return (
    <div className="App">
      <input onChange={inputChangeHandler} className="inputField" />
      <input
        type={"number"}
        onChange={inputChangeHandler2}
        className="inputField2"
      />
      <button onClick={clickHandler}></button>
      {expenseLog.map((expense) => (
        <p>
          {expense.name} {expense.amount}
        </p>
      ))}
    </div>
  );
}

export default App;
like image 40
Satel Avatar answered Oct 23 '25 07:10

Satel



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!