I'm trying to create an application with a 'bathtub' and 2 buttons. The tub has 5 levels of water. When you click the first button, the tub fills one level every 2 seconds until reaching 5. The other button drains the tub until level 0. The increaseWaterLevel and decreaseWaterLevel functions are only firing once and I'm not sure why.
import React, { useState } from "react";
const App = () => {
const [waterLevel, setWaterLevel] = useState(0);
let fillTub;
let drainTub;
const increaseWaterLevel = () => {
if (waterLevel < 5) {
const newWaterLevel = waterLevel + 1;
setWaterLevel(newWaterLevel);
} else {
clearInterval(fillTub);
}
};
const decreaseWaterLevel = () => {
if (waterLevel > 0) {
const newWaterLevel = waterLevel - 1;
setWaterLevel(newWaterLevel);
} else {
clearInterval(fillTub);
}
};
return (
<div>
<div>Bathtub</div>
<button
onClick={() => {
fillTub = window.setInterval(increaseWaterLevel, 2000);
}}
>
increaseWaterLevel
</button>
<button
onClick={() => {
drainTub = window.setInterval(decreaseWaterLevel, 2000);
}}
>
decreaseWaterLevel
</button>
</div>
);
};
export default App;
update the counter is working but does not stop and waterLevel remains at 0. What am I doing wrong?
import React, { useState } from "react";
const App = () => {
const [waterLevel, setWaterLevel] = useState(0);
const [intervalId, setIntervalId] = useState(0);
const increaseWaterLevel = () => {
const newWaterLevel = setInterval(() => {
if (waterLevel > 4) {
clearInterval(intervalId);
} else {
setWaterLevel((prevWaterLevel) => prevWaterLevel + 1);
}
}, 2000);
setIntervalId(newWaterLevel);
};
const decreaseWaterLevel = () => {
const newWaterLevel = setInterval(() => {
if (waterLevel > 0) {
setWaterLevel((prevWaterLevel) => prevWaterLevel - 1);
} else {
clearInterval(intervalId);
}
}, 2000);
setIntervalId(newWaterLevel);
};
return (
<div>
<div>Bathtub</div>
<button onClick={increaseWaterLevel}>increaseWaterLevel</button>
<button onClick={decreaseWaterLevel}>decreaseWaterLevel</button>
</div>
);
};
export default App;
Let me first say that i started learning react like 1 week ago and i still have some doubt and this code may be really bad even if it works, but i still want to help so this is the code.
The main problem here is that useState function is an async function and it doesn't update in real time your variable so in this case checking waterLevel value without useEffect will not work.
import React, { useState, useEffect } from "react";
const App = () => {
const [waterLevel, setWaterLevel] = useState(0);
const [actionType, setActionType] = useState();
useEffect(() => {
const interval = setInterval(() => {
if (actionType == "increase" && waterLevel < 5)
setWaterLevel(waterLevel + 1);
if (actionType == "decrease" && waterLevel > 0)
setWaterLevel(waterLevel - 1);
}, 2000);
return () => clearInterval(interval);
}, [actionType, waterLevel]);
return (
<div>
<div>Bathtub</div>
<button onClick={() => setActionType("increase")}>
increaseWaterLevel
</button>
<button onClick={() => setActionType("decrease")}>
decreaseWaterLevel
</button>
<h1>{waterLevel}</h1>
</div>
);
};
export default App;