const [lap, setLap] = useState([]);
function start(){
if(!isStart){
starting = Date.now() - elapsed;
isStart = true;
timer = setInterval(update, 1000);
console.log("timer is activated");
}
}
function stop(){
if(isStart){
isStart = false;
clearInterval(timer);
}
}
function reset(){
isStart = false;
elapsed = 0;
document.getElementById("time").textContent = "00:00:00";
clearInterval(timer);
starting = 0;
}
}
function update(){
var curr = Date.now();
elapsed = curr - starting;
var min = Math.floor(elapsed/(1000*60));
var sec = Math.floor((elapsed/1000)%60);
var msec = Math.floor((elapsed%1000)/10);
var time = [min, sec, msec]
time = time.map((element) => pad(element));
var time_str = time[0] + ":" + time[1] + ":" + time[2];
document.getElementById("time").textContent = time_str;
console.log(time_str)
}
const lap_update = (val) => {
setLap(lap => [...lap, val]);
}
<div id="lap" onClick={() => lap_update(document.getElementById("time").textContent)}>LAP</div>
The above are the code snippets for a Stopwatch is lap functionality.
Unfortunately, my lap_update function when clicked, is causing the start/stop/reset functions to malfunction.
(Stop function and reset function not working, and start function is double rendering).
I really am not able to understand why, and what changes are needed in the setLap statment.
Please help!
Trying to figure out the issue with the setLap statement which is causing the other functions to malfunction (till Lap function is called, the program is running fine).
2
Answers
when you update the
lap
state withsetLap
it causes a rerender of the component. So, If the start function is coupled to a re-render in some way it might get invoked many timesfor this, we can use a
useRef
hook to keep track of the timer and check if the stopwatch is running to avoid issues with rerenders. this will make sure updates to the state don’t interfere with the timing functions.I have made these changes to youre code and here is a working example
the
timerRef
keeps track of the interval timer. this will prevent issues caused by rerendersstartingRef
is for holding the starting time to have a consistent timing calculations even when the component rerendersRead more about
useRef
hook hereThe issue with
setLap
function causing other functions to malfunction in your React application likely stems from how state and side effects are being managed in React, especially when dealing with functional components and hooks.Let’s encapsulate your stopwatch logic within React component and make sure that state changes are managed correctly.
Why Your Original Code Malfunctions:
Direct DOM Manipulation: Directly manipulating the DOM (
document.getElementById('time').textContent
) can conflict with React’s virtual DOM updates.State Not Synchronized: Your functions were relying on local variables (isStart, elapsed) that were not synchronized with React’s state management, leading to inconsistent behavior.
State Changes and Re-renders: Calling
setLap
inside an event handler triggers a state update, causing a re-render. If the component isn’t structured to handle re-renders properly, this can lead to unexpected behavior.