I understand useInterval allows you to pass functional components as parameters, so I'm trying to take advantage of that and setting states with values used inside a functional component. In the following code, I want the ExecutionsPage to fetch projectScans and isProjectScansFetchComplete, which are returned from the useFetchProjectScansByUser() hook as an array:
1 const ExecutionsPage: React.FC = () => {
2 let user:string|null = sessionStorage.getItem('user')
3 const UPDATE_TABLE_TIMER: number = 30000; // Time (ms) until we call the API again to update the scans table
4 const [stateProjectScans, setStateProjectScans] = useState<Array<IProjectScan>>([]);
5 const [stateIsProjectScansFetchComplete, setStateIsProjectScansFetchComplete] = useState<boolean>(false);
6 function CallProjectScans(){
7 let [projectScans, isProjectScansFetchComplete] = useFetchProjectScansByUser(user)
8 return [projectScans, isProjectScansFetchComplete]
9 }
10 useEffect(() => {
11 let [projectScans, isProjectScansFetchComplete] = CallProjectScans()
12 // @ts-ignore
13 setStateProjectScans(projectScans)
14 // @ts-ignore
15 setStateIsProjectScansFetchComplete(isProjectScansFetchComplete)
16 }, [])
17 const GetProjectScans = () => {
18 let [projectScans, isProjectScansFetchComplete] = useFetchProjectScansByUser(user);
19 setStateProjectScans(projectScans)
20 };
21 // @ts-ignore
22 useInterval(GetProjectScans(), UPDATE_TABLE_TIMER)
In using this code, I'm getting this error: "Error: Too many re-renders. React limits the number of renders to prevent an infinite loop." So, with all that said, here are my questions:
- Readability-wise, am I using too many functions?
- The goal is to call the React hook on line 7 every 30 seconds and update the states on lines 4 and 5. Is there a better way to do this than how I'm currently attempting it?
- I tried using useEffect() to prevent the aforementioned error (by setting the states on the initial render of the ExecutionsPage, instead of rerendering it), but I am still getting it. Why?
Edit: Here's the function definition of useFetchProjectScansByUser():
export const useFetchProjectScansByUser = (user: string|null): [IProjectScan[], boolean] => {
const [projectScans, setProjectScans] = useState<IProjectScan[]>([]);
//update here
const [isProjectScansFetchComplete, setIsProjectScansFetchComplete] = useState<boolean>(false);
const {enqueueSnackbar, } = useSnackbar();
useEffect(() => {
...
/*function callJSONFunction(json) {
let projectScans: IProjectScan[] = createProjectScansFromJSON(json);
setProjectScans(projectScans);
}*/
const fetchProjectScans = async () => {
try {
const response = await fetch(URL);
if (!response.ok) throw response.statusText;
const json = await response.json();
let projectScans: IProjectScan[] = createProjectScansFromJSON(json);
setProjectScans(projectScans);
...
finally {
setIsProjectScansFetchComplete(true);
}
};
fetchProjectScans();
}
}, []);
return [projectScans, isProjectScansFetchComplete];
}