score:1

function useFetchPerson() {
  const dispatch = useDispatch();
  const personRef = useRef(); // <-- ref to hold person state value
    
  const person = useSelector((state) => state.person);

  useEffect(() => {
    personRef.current = person; // <-- cache person value
  }, [person]);

  const startTimeRef = useRef();
  const idRef = useRef();

  const [chances, setChances] = useState(3);

  const fetchPerson = (timestamp) => {
    const elapse = timestamp - startTimeRef.current; 
        
    // a. run requestAnimationFrame if less than 5 seconds
    if (elapse < 5 * 1000) {
      idRef.current = requestAnimationFrame(fetchPerson);
      return;
    }

    // b. safety hatch to break from this recursive function
    if (!personRef.current?.fetchStatus) { // <-- reference personRef current value
      setChances(chances => chances - 1) ;
      return
    }
    if (chances === 0) return;
        
    // c. go fetch api and save into redux store if 5 sec later and update the startTime 
    dispatch(fetchPersonReduxThunk());
    startTimeRef.current = performance.now();
    idRef.current = requestAnimationFrame(fetchPerson);
  };

  useEffect(()=>{
    startTimeRef.current = performance.now();
    idRef.current = requestAnimationFrame(fetchPerson)
        
    return () => cancelAnimationFrame(idRef.current)
  }, []);

  return person;
}

Related Query

More Query from same tag