I want to show the current time(MM/DD/YY hh:mm:ss) in react native app like a clock, and get update every seconds, I tried using new Date() and set it in state, but the time don't update unless I refresh the page.
I also tried using setInterval function in render(), it do got update but it's expensive for CPU. is there a good method to realise the function?
state = {
curTime: null,
}
render(){
setInterval(function(){this.setState({curTime: new Date().toLocaleString()});}.bind(this), 1000);
return (
<View>
<Text style={headerStyle.marginBottom15}>Date: {this.state.curTime}</Text>
</View>
);
}
Just move setInterval
into componentDidMount function.
Like this :
componentDidMount() {
setInterval( () => {
this.setState({
curTime : new Date().toLocaleString()
})
},1000)
}
This will change state and update every 1s.
This method works fine and displays MM/DD/YY hh:mm:ss format
class Clock extends React.Component {
constructor(props) {
super(props);
this.state = {
time: new Date().toLocaleString()
};
}
componentDidMount() {
this.intervalID = setInterval(
() => this.tick(),
1000
);
}
componentWillUnmount() {
clearInterval(this.intervalID);
}
tick() {
this.setState({
time: new Date().toLocaleString()
});
}
render() {
return (
<p className="App-clock">
The time is {this.state.time}.
</p>
);
}
}
original link : https://openclassrooms.com/courses/build-web-apps-with-reactjs/build-a-ticking-clock-component
I got the answer. The code below also works.
componentWillMount(){
setInterval(function(){
this.setState({
curTime: new Date().toLocaleString()
})
}.bind(this), 1000);
}
I would recommend to prefer using setTimeout
instead of setInterval
, indeed, the browser may be overhelmed by heavy processing and in that case you would probably prefer updating the clock less often instead of queuing several updates of the state.
With setTimeout
it is also a bit easier to leverage the Page Visibility API to completely stop the clock when the page is hidden (see https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API).
export default class MyClock {
constructor(props) {
super(props);
this.state = {
currentTime: Date.now(),
};
}
updateCurrentTime() {
this.setState(state => ({
...state,
currentTime: Date.now(),
}));
this.timeoutId = setTimeout(this.updateCurrentTime.bind(this), 1000);
}
componentWillMount() {
this.updateCurrentTime();
document.addEventListener('visibilitychange', () => {
if(document.hidden) {
clearTimeout(this.timeoutId);
} else {
this.updateCurrentTime();
}
}, false);
}
componentWillUnmount() {
clearTimeout(this.timeoutId);
}
}
in react hooks, it can be done like this:
import React, { useState, useEffect } from "react";
const [dt, setDt] = useState(new Date().toLocaleString());
useEffect(() => {
let secTimer = setInterval( () => {
setDt(new Date().toLocaleString())
},1000)
return () => clearInterval(secTimer);
}, []);
Full Code here:
import React, { Component } from 'react';
import { Text, View } from 'react-native';
export default class KenTest extends Component {
componentDidMount(){
setInterval(() => (
this.setState(
{ curTime : new Date().toLocaleString()}
)
), 1000);
}
state = {curTime:new Date().toLocaleString()};
render() {
return (
<View>
<Text>{'\n'}{'\n'}{'\n'}The time is: {this.state.curTime}</Text>
</View>
);
}
}