Can anyone tell me what is wrong with this code pls ?
import React, { useState } from "react";
const Createcolumn = () => {
const [sum, setSum] = useState('');
const [dailySum, setDailySum] = useState(0);
const [daysOfWork, setDaysOfWork] = useState(0);
const [fare, setFare] = useState(0);
const dailySumHandler = (e) => {
setDailySum(Number(e.target.value));
};
const daysOfWorkHandler = (e) => {
setDaysOfWork(Number(e.target.value));
};
const fareHandler = (e) => {
setFare(Number(e.target.value));
};
setSum(dailySum * daysOfWork fare);
return (
<div>
<div className="column">
<h1>Name</h1>
<h1>Daily</h1>
<h1>Days of Work</h1>
<h1>Fare</h1>
<h1>Total</h1>
</div>
<div className="column">
<div>
<h1>Nodirbek</h1>
</div>
<div>
<input type="text" onChange={dailySumHandler} />
</div>
<div>
<input type="text" onChange={daysOfWorkHandler} />
</div>
<div>
<input type="text" onChange={fareHandler} />
</div>
<div>
<h1>{sum}</h1>
</div>
</div>
</div>
);
};
export default Createcolumn;
I cannot set my Sum to h1, it is saying too much render I tried to make a function as well, but it doesn't work either
I cannot set my Sum to h1, it is saying too much render I tried to make a function as well, but it doesn't work either
CodePudding user response:
The problem is you're calling this directly into your render
setSum(dailySum * daysOfWork fare);
Once setSum
gets triggered, it will cause UI re-rendering which calls render
function again. And again setSum
will continue being called (it's like deadlock)
Here is a possible fix
import React, { useState } from "react";
const Createcolumn = () => {
const [dailySum, setDailySum] = useState(0);
const [daysOfWork, setDaysOfWork] = useState(0);
const [fare, setFare] = useState(0);
const dailySumHandler = (e) => {
setDailySum(Number(e.target.value));
};
const daysOfWorkHandler = (e) => {
setDaysOfWork(Number(e.target.value));
};
const fareHandler = (e) => {
setFare(Number(e.target.value));
};
return (
<div>
<div className="column">
<h1>Name</h1>
<h1>Daily</h1>
<h1>Days of Work</h1>
<h1>Fare</h1>
<h1>Total</h1>
</div>
<div className="column">
<div>
<h1>Nodirbek</h1>
</div>
<div>
<input type="text" onChange={dailySumHandler} />
</div>
<div>
<input type="text" onChange={daysOfWorkHandler} />
</div>
<div>
<input type="text" onChange={fareHandler} />
</div>
<div>
<h1>{dailySum * daysOfWork fare}</h1>
</div>
</div>
</div>
);
};
export default Createcolumn;
CodePudding user response:
You can't use calls to hook setters in the body of the function, it'll cause a rerender, which will cause a rerender, which will cause rerender, and so and so forth.
Instead initialize your value when you call the hook:
const [sum, setSum] = useState(dailySum * daysOfWork fare);
CodePudding user response:
You have to use arrow function notation while calling those functions and pass the event that's what's causing re-renders.
Your code:
</div>
<div>
<input type="text" onChange={dailySumHandler} />
</div>
<div>
<input type="text" onChange={daysOfWorkHandler} />
</div>
<div>
<input type="text" onChange={fareHandler} />
</div>
Fix:
</div>
<div>
<input type="text" onChange={(e) => dailySumHandler(e)} />
</div>
<div>
<input type="text" onChange={(e) => daysOfWorkHandler(e)} />
</div>
<div>
<input type="text" onChange={(e) => fareHandler(e)} />
</div>
CodePudding user response:
The why: You're changing the state in every render not based on some change in your component, remember how react works: you change the state => react re-render your component all over again.
At every render you tell react to change the state(setSum(...)
) which will tell react to re-render, all over again, it enters a loop of render and a call to setSum
which cause a re-render forever.
Solution:
Don't use state if your data can be computed based on other states, it looks like the sum
only depends on other states, why create a state for it if you can calculate it easily from other states?
Delete the line:
const [sum, setSum] = useState('');
and just add the line(before the return statement)
let sum = (dailySum * daysOfWork fare);
CodePudding user response:
This is typically the kind of scenario you want to use useMemo
to solve:
import { useMemo } from "react"
const sum = useMemo(
() => dailySum * daysOfWork fare,
[dailySum, daysOfWork, fare]
);
This allows you to automatically recompute the sum whenever any of its components changes without having to keep track of an additional state and setter.
CodePudding user response:
The problem here is that when you try to use setstate() before you bring in the
return()
statement it will bring out that error.
The solution is that the setSum() have to fire after the first render after the return statement