I have a timer on my web app on the home component, that is doing some countdown. Here's the Home
component:
export default class Home extends React.Component {
timer() {
var countDownDate = new Date("Sep 5, 2018 15:37:25").getTime();
var x = setInterval(() => {
var now = new Date().getTime();
var distance = countDownDate - now;
var days = Math.floor(distance / (1000 * 60 * 60 * 24));
var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
var seconds = Math.floor((distance % (1000 * 60)) / 1000);
document.getElementById("timer").innerHTML = days + "d " + hours + "h "
+ minutes + "m " + seconds + "s ";
if (distance < 0) {
clearInterval(x);
document.getElementById("timer").innerHTML = "EXPIRED";
}
}, 1000);
}
componentDidMount() {
$('.monster').fadeIn('slow');
this.timer();
}
render() {
return (
<div id="timer"></div>
)
}
}
Here's my Questions
component:
export default class AssignmentsComponent extends React.Component {
render() {
return (
<h1>Questions Component</h1>
)
}
}
This is my App.js
component:
export default class App extends Component {
render() {
return (
<div className="App">
<NavigationComponent {...this}/>
{/*<CheckIfHasCurrentTasksComponent user={firebase.auth().currentUser}/>*/}
{/*{this.state.user ? <Questions/> : <Home/>}*/}
</div>
);
}
}
And just in case it matters this is my Navigation
component:
export default class NavigationComponent extends React.Component {
render() {
return (
<BrowserRouter>
<React.Fragment>
<Navbar className="fixedTop custom_navbar half_transparent">
<Nav className="float_right">
<NavItem className="custom_button_navbar"><span>pobierz</span></NavItem>
{
firebase.auth().currentUser !== null ?
<React.Fragment>
<LinkContainer id="assignments" to='/assignments'>
<NavItem>Zadania</NavItem>
</LinkContainer>
<NavItem onClick={logout.bind(this)}>Wyloguj się</NavItem>
</React.Fragment>
:
<NavItem onClick={this.openLogin}
className="custom_button_navbar"><span>Zaloguj się</span></NavItem>
}
</Nav>
</Navbar>
<Switch>
<Route exact path="/assignments" render={
() => (firebase.auth().currentUser === null ?
<Redirect to='/'/> : <AssignmentsComponent/>)
}/>
<Route exact path='/assignment/:id' render={
props => (
firebase.auth().currentUser === null ?
<Redirect to='/'/> : <CheckIfHasCurrentTasksComponent {...props}/>
)
}/>
<Route exact path="/" component={HomeComponent}/>
</Switch>
<LoginFormComponent show={this.state.show} changeShowState={this.changeShowState}/>
</React.Fragment>
</BrowserRouter>
)
}
}
What the problem is: When I open home component, all goes well, the timer fires up, and it's all pretty. But if I go to questions component, the timer()
method is still trying to run, even though I didn't call it anywhere in the Assignments
component. That's when the app crashes.
Adding a try catch
block inside the timer() method like this:
try {
document.getElementById("timer").innerHTML = days + "d " + hours + "h "
+ minutes + "m " + seconds + "s ";
if (distance < 0) {
clearInterval(x);
document.getElementById("timer").innerHTML = "EXPIRED";
}
} catch (e) {
}
Solves the issue, but I'm pretty sure it's a bad practice.
So how can I make it only be called when the Home
component is being rendered?