Reputation: 1150
I'm creating interval counter and below code is working fine. But I have few questions about this code which I do not understand.
import React, { useState, useEffect } from 'react';
import {View, Text} from 'react-native'
const Interval = () => {
const [seconds, setSeconds] = useState(0);
useEffect(() => {
const interval = setInterval(() => {
console.log(`seconds: ${seconds}`)
setSeconds(seconds => seconds + 1);
}, 1000);
return () => clearInterval(interval);
}, []);
return (
<View>
<Text>
{seconds} seconds have elapsed since mounting.
</Text>
</View>
);
};
export default IntervalExample;
setSeconds(seconds => seconds + 1);
instead setSeconds(seconds + 1);
more simply ?console.log(`seconds: ${seconds}`)
is always log as 0
?Upvotes: 2
Views: 1586
Reputation: 106
use this ;
useEffect(() => {
const interval = setInterval(() => {
setSeconds(seconds + 1);
console.log(seconds)
}, 1000);
return () => clearInterval(interval);
}, [seconds]);
Upvotes: 1
Reputation: 915
to run useEffect
You need to pass variables as the second parameter (in your case, it is seconds
). When this variable has changed then useEffect
will be run again.
From docs:
If you pass an empty array ([]), the props and state inside the effect will always have their initial values. While passing [] as the second argument is closer to the familiar componentDidMount and componentWillUnmount mental model, there are usually better solutions to avoid re-running effects too often. Also, don’t forget that React defers running useEffect until after the browser has painted, so doing extra work is less of a problem.
that is way, You need to pass second varable to useEfect:
useEffect(() => {...}, [seconds])
and in that case You can use setSeconds(seconds + 1);
instead of passing function.
Complete code:
useEffect(() => {
const interval = setInterval(() => {
console.log(`seconds: ${seconds}`)
setSeconds(seconds + 1)
}, 1000)
return () => clearInterval(interval)
}, [seconds])
Upvotes: 1