When I load my page in React I want some value to increment from 0 to certain given value (let's say 50 ), so as a page loads I want to see value incrementation from 0 to 50 ( 0 1 2 3 4 ... 50 ) I've tried this
const [number, setNumber] = useState(0);
const limiter = 50;
React.useEffect(() => {
const incrementer = setInterval(() => {
if (number === limiter) {
clearInterval(incrementer);
} else {
setNumber(number 1);
}
}, 500);
},[]);
But for some reason it goes like ( 0 1 1 2 0 1 2 0 )
CodePudding user response:
Why your code doesn't work
The reason why your code doesn't work is because you did not use your state number
as a dependency. This means your useEffect won't get the latest value of number
for your if (number === limiter)
comparison.
Working Solution
This will be a working solution, and you need to clearInterval before declaring a new setInterval.
the variable timer
also has to be set outside the function so it doesn't get re-declared everytime it renders.
let timer;
const App = () => {
const [ counterState, setCounter ] = React.useState(0)
React.useEffect(() => {
clearInterval(timer)
timer = setInterval(() => {
if (counterState === 100) {
clearInterval(timer)
return
}
setCounter(prev => prev 1)
counter
},10)
return () => clearInterval(timer)
},[counterState])
return (<div>{counterState}</div>)
}
ReactDOM.render(<App />, document.body);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
PS: setTimeout works as well.
CodePudding user response:
React.useEffect(() => {
const incrementer = setInterval(() => {
setNumber((c) => {
if(c < limiter) return c 1;
clearInterval(incrementer);
return c;
});
}, 500);
},[]);