Reputation: 51
I'd like some help understanding why my React Component isn't working. I'm trying work on my React/Js fundamentals by making a basic timer. The component is rendering great, just nothing is happening. I'm looking at the React Profiler on Chrome and my variables seem to be updating correctly.
I know it's basic, I'd just rather start and fix my mistakes and learn on the way.
Any help whatsoever would be greatly appreciated!
import React from 'react'
var sec = 0;
var min = 0;
var hrs = 0;
var timer_id;
// Helper Functions
function tick(){
sec++;
if (sec >= 60){
sec = 0;
min ++;
if (min >= 60){
min = 0;
hrs++;
};
};
}
function add(){
tick();
timer();
}
function timer(){
console.log("TIMER");
timer_id = setTimeout(add, 1000);
}
// Clock Component
class Clock extends React.Component{
render(){
timer();
return (
<div className="clock-face">
<h4> {hrs} : {min} : {sec}</h4>
<button
onClick = {() => clearTimeout(timer_id)}> Stop </button>
</div>
);
}
}
export default Clock;
Upvotes: 0
Views: 1058
Reputation: 168986
React components only get rerendered when their props or state changes (or when forced to rerender, but we don't do that). You're updating hrs/min/sec in global variables; those aren't tracked by React.
In addition, it's not a good idea to have render()
execute a side effect (timer()
in your case); React may elect to render your function more than once.
Here's an example of your clock as a class component that ticks along and cleans the timer up after it's unmounted.
The magic that causes the rerendering here is this.setState
being called.
import React from "react";
function divmod(a, b) {
return [Math.floor(a / b), a % b];
}
class Clock extends React.Component {
state = { time: 0 };
componentDidMount() {
this.timer = setInterval(this.tick, 1000);
}
componentWillUnmount() {
clearInterval(this.timer);
}
tick = () => {
this.setState(({ time }) => ({ time: time + 1 }));
};
render() {
const { time } = this.state;
const [hmins, secs] = divmod(time, 60);
const [hrs, mins] = divmod(hmins, 60);
return (
<div className="clock-face">
<h4>
{" "}
{hrs} : {mins} : {secs}
</h4>
</div>
);
}
}
Upvotes: 1