skip to Main Content

I have a reactJS app that calls an API using a hook:

useEffect(() => {
    const fetchData = async () => {
        setIsLoading(true);
        const res = await fetch("/api/r/" + sid);
        const result = await res.json();
        setResult(result);
        setIsLoading(false);
    };

    fetchData().catch(console.error);
}, [sid]);

sometimes this API takes a long time to return all the data, in there a way to trigger an event after n seconds if I didn’t receive the data yet, so I can show a message to the user?

4

Answers


  1. You could use setTimeout() to delay some actions an example would be:

    useEffect(() => {
        const fetchData = async () => {
            setIsLoading(true);
            const res = await fetch("/api/r/" + sid);
            const result = await res.json();
            setResult(result);
            setIsLoading(false);
    
            setTimeout(() => {
               console.log('I will appear after 1000ms');
            }, 1000);
        };
    
        fetchData().catch(console.error);
    }, [sid]);
    
    Login or Signup to reply.
  2. If you want to show after a specific amount of time, you can you setTimeout inside the useEffect. Like this:

    Edit: Remember to remove/clean your timeout on a useEffect cleanup function.

    useEffect(() => {
        const fetchData = async () => {
            setIsLoading(true);
            const res = await fetch("/api/r/" + sid);
            const result = await res.json();
            setResult(result);
            setIsLoading(false);
        };
    
        fetchData().catch(console.error);
    
       // I am using 1 sec as an example
        const messageTimeout = setTimeout(()=>{
           showMessage();
        }, 1000);
        
        return () => clearTimeout(messageTimeout);
    
    }, [sid]);
    
    Login or Signup to reply.
  3. You can create a custom hook something like below

    const useFetch(() => {
     const [isLoading, setIsLoading] = useState(false)
     const [error, setError] = useState()
     const [data, setData] = useState()
     // use api call here and set the above states
     return {isLoading, error, setData};
    })
    

    or you can use https://tanstack.com/query/v4/docs/react/reference/useQuery

    Login or Signup to reply.
  4. you should use a timer to cache setTimeout and then when request not back to
    show message or back to cancel. like:

      const timer = useRef(null);
    
      useEffect(() => {
        const fetchData = async () => {
          setIsLoading(true);
          if(timer.current) clearTimeout(timer.current)
          timer.current = setTimeout(() => {
            console.log('request slow, please be paint!')
          }, 20000)
    
          const res = await fetch('/api/r/' + sid);
          const result = await res.json();
    
          clearTimeout(timer.current)
          
          setResult(result);
          setIsLoading(false);
        };
       
        fetchData();
      }, [sid]);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search