Polling hook useRef

do not useState for internal values. which are not relevnat to rendering
This will only trigger unnecessary rerenders
This commit is contained in:
djmil 2023-11-10 13:10:30 +01:00
parent 453a45d980
commit cd62d90de8
4 changed files with 26 additions and 20 deletions

View File

@ -1,4 +1,4 @@
import usePolling from '../util/Polling';
import usePolling from '../hook/Polling';
export default function useGamesApi(dispatchGames) {

View File

@ -1,5 +1,5 @@
import { useState } from "react";
import usePolling from "../util/Polling";
import usePolling from "../hook/Polling";
export default function useLeaderboardApi() {
const [leaderboard, setLeaderboard] = useState(null);

View File

@ -1,4 +1,4 @@
import usePolling from "../util/Polling";
import usePolling from "../hook/Polling";
import useUserReducer from "../reducer/user";
export default function useUserApi() {

View File

@ -1,4 +1,4 @@
import { useState, useCallback, useEffect, } from "react"
import { useState, useRef, useCallback, useEffect, } from "react"
/*
- uri: string
@ -9,13 +9,18 @@ import { useState, useCallback, useEffect, } from "react"
*/
export default function usePolling(uri, onResponce, mode = null) {
const [initialPoll, setInitialPoll] = useState(true);
const [isPolling, setPolling] = useState(false);
const [intervalTimer, setIntervalTimer] = useState(null);
const initialPollRef = useRef(true);
const initialPoll = initialPollRef.current;
const intervalTimerIdRef = useRef(null);
const intervalTimerId = intervalTimerIdRef.current;
const pollData = useCallback(() => {
setPolling(true);
setInitialPoll(false);
initialPollRef.current = false;
fetch(uri)
.then((responce) => {
@ -23,8 +28,7 @@ export default function usePolling(uri, onResponce, mode = null) {
if (typeof mode?.interval_sec === 'number') {
console.log("Schedule", uri, "fetch in", mode.interval_sec, "sec");
const intervalTimer = setTimeout(pollData, mode.interval_sec * 1000);
setIntervalTimer(intervalTimer);
intervalTimerIdRef.current = setTimeout(pollData, mode.interval_sec * 1000);
}
return responce.json();
@ -35,21 +39,23 @@ export default function usePolling(uri, onResponce, mode = null) {
.catch((err) => {
console.warn(err.message);
})
}, [uri, mode, onResponce]);
}, [uri, mode, onResponce, initialPollRef, intervalTimerIdRef]);
const stopPollInterval = useCallback(() => {
console.log("Cancel scheduled fetch for", uri);
clearTimeout(intervalTimerId);
intervalTimerIdRef.current = null;
initialPollRef.current = true;
}, [uri, intervalTimerId, intervalTimerIdRef, initialPollRef]);
useEffect(() => {
if ((initialPoll || (typeof mode?.interval_sec === 'number' && intervalTimer === null)) && !isPolling) {
if ((initialPoll || (typeof mode?.interval_sec === 'number' && intervalTimerId === null)) && !isPolling) {
pollData();
} else
if (mode?.interval_stop && intervalTimerId) {
stopPollInterval();
}
}, [initialPoll, mode, intervalTimer, isPolling, pollData]);
if (mode?.interval_stop && intervalTimer) {
console.log("Cancel scheduled fetch for", uri);
clearTimeout(intervalTimer);
setIntervalTimer(null);
setInitialPoll(true);
}
}, [initialPoll, mode, intervalTimerId, isPolling, pollData, stopPollInterval]);
return isPolling;
}