I have three different state variables in a component. Two of the states is connected to a range slider that updates the state when i move the slider. One is for cost and one is for time.
My questions is, how do i update the third state based on information from the first two states?
function Calculator() {
const [loanAmount, setLoanAmount] = useState(100000);
const [loanTime, setLoanTime] = useState(5);
const calculateCost = () => {
const totalMonths = loanTime * 12;
const monthlyFee = 0.00825;
const monthlyFeePlusOne = 1.00825
const totalPrice =
(loanAmount*0.00825)*(Math.pow((1 0.00825), 60))/(Math.pow((1 0.00825), 60)-1);
return Math.round(totalPrice);
};
const [calculation, setCalculation] = useState(calculateCost());
<input
className="slider"
type="range"
min="20000"
max="200000"
value={loanAmount}
step="10000"
onChange={(e) => setLoanAmount(e.target.value)}
/>
<label>{loanAmount}</label>
<input
className="slider"
type="range"
min="2"
max="10"
value={loanTime}
step="1"
onChange={(e) => setLoanTime(e.target.value)}
setCalculation
/>
<label> {calculation} </label>
CodePudding user response:
Use useEffect()
with the first and second state values in the dependency array to update the third state value when the first/second state values change:
useEffect(() => {
setCalculation(calculateCost());
}, [loanAmount, loanTime]);
CodePudding user response:
The third value isn't state because you can always calculate it from other state/props.
Try replacing
const [calculation, setCalculation] = useState(calculateCost());
with
const calculation = calculateCost();
Making it state is redundant and complicates the code.
CodePudding user response:
The first answer suggests doing it using useEffect
which is the typical way a lot of developers do it, but that's not what useEffect
is for, as stated in the React documentation: If your effect only adjusts some state based on another state, you might not need an effect.
So, you should perform this operation in the onChange
event of your inputs since the state update is tied to it and not the render itself (which is what useEffect
is for).
const handleLoanAmountInputChange = (e) => {
const amount = e.currentTarget.value;
setLoanAmount(amount);
const cost = calculateCost(amount, loanTime); // you will ned to update your function to use parameters, this way it will also easier to test the function
setCalculation(cost);
}
<input
onChange={handleLoanAmountInputChange}