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;
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.
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;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With