Reputation: 1797
A simple react script:
import React, { useState, useEffect } from 'react';
export default function App() {
const [indexesArray, setIndexesArray] = useState([]);
const doit = () => {
const arr = [];
for(let i = 0;i<10;i++){
arr.push(i);
}
setIndexesArray(arr);
}
useEffect(() => {
if(!indexesArray.length){
doit();
setInterval(function(){
console.log('indexesArray',indexesArray);
}, 2000);
}
}, [indexesArray]);
return (
<>
{indexesArray && JSON.stringify(indexesArray)}
</>
);
}
On the page I can see the content of the array. However, printing the array in the console each 2 seconds shows an empty array. What am I missing?
Upvotes: 0
Views: 167
Reputation: 370679
The indexesArray
binding being used by the setInterval
is the array that exist in the scope that the interval was created - which is empty. Re-rendering of the components doesn't mutate the existing state - it runs the whole app
again, in a whole different scope (but this time with new values returned by useState
).
In your effect hook, set the interval only if the array has been populated (and don't forget to clear the interval afterwards).
function App() {
const [indexesArray, setIndexesArray] = React.useState([]);
const doit = () => {
const arr = [];
for(let i = 0;i<10;i++){
arr.push(i);
}
setIndexesArray(arr);
}
React.useEffect(() => {
if(!indexesArray.length){
doit();
} else {
const intervalId = setInterval(function(){
console.log('indexesArray',indexesArray);
}, 2000);
return () => clearInterval(intervalId);
}
}, [indexesArray]);
return indexesArray && JSON.stringify(indexesArray)
}
ReactDOM.render(<App />, document.querySelector('.react'));
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div class='react'></div>
Upvotes: 1