React native How to fetch from api every x minutes

 componentDidMount(){
  this.timer = setInterval(()=> this.getMovies(), 1000)
 }

async getMovies(){

 fetch('https://facebook.github.io/react-native/movies.json', {method: "GET"})
  .then((response) => response.json())
  .then((responseData) =>
  {
    //set your data here
     console.log(responseData);
  })
  .catch((error) => {
      console.error(error);
  });

}

If you want run your service in background then there is only one option you have that is headless js https://facebook.github.io/react-native/docs/headless-js-android.html or npm based on headless js like https://github.com/jamesisaac/react-native-background-task

headless base service can have minimum periodic frequency 15 not less than that

if need to run service lesser than that eg 5 minutes then you can use combination of headless js and setinterval like

   BackgroundTask.define(async () => { //headless based runs every 15 minute
        console.log('headless js service start')

         this._interval = setInterval(() => {
         console.log('setinterval for 5 minute start')
        // Your code
         }, 300000);

          BackgroundTask.finish()
     })

then inside your any component method like componentwillmount you need to schedule background task like

 componentDidMount() {
      BackgroundTask.schedule({
      period: 900, // Aim to run every 15mins 
      })
      }

you can use setinterval alone without headless JS but will be stop by android to save battery/resource

Note : to test these things you have to use real device as physical device go in doze mode or do things like stop background app to save battery/resource unlike emulators


I'm a little late to the party but I had to do something similar. I was making an API request to a server that fetches a bunch of locations, does some calculations and passes the data to a callback function in another part of the app to update a Map. I wanted this to run every "x" seconds. This is what I did:

I created a custom hook that I call from the map screen. I had two states I wanted to return (businessLocations, error). I created a timer at the top of the file that looks like this:

const [render, setRender] = useState(false);
 
useEffect(() => {
   setTimeout(() => {
      setRender(!render);
   }, 20000);
}, [isScreenFocused, render]);

This was recreated every time the screen was focused or the render state changed. As you can see I trigger the render state to change every time 20 seconds is up causing the timer to re-start.

Below the useEffect call I created a second useEffect call that looks like this:

const fetching = useRef(false);

useEffect(() => {

        const searchForLocations = async () => {

            fetching.current = true;

            await requestAllLocations()
                .then((locations) => {

                    const results = locations.map(loc => {
                        return createBusinessFromAPI(loc);
                    });

                    setBusinessLocations(results);
                    locationsCallback(results);

                    fetching.current = false;

                }).catch((error) => {
                    fetching.current = false;
                    throw error;
                });
        };

        if (!fetching.current) {
            searchForLocations().catch(error => setError(error));
        }

    }, [isScreenFocused, render]);

As you can see here, I use the hook useRef (which doesn't change from render to render) to determine if the last request is still processing. If it is, I don't call searchForLocations() on this render cycle and simply wait for the next one. You can also see that this entire useEffect call is triggered when the timer is up because I use the render state as a dependency here too.

It may not be a perfect solution. I'm currently trying to refine it a little. But, it has worked for me so far.

Here is the entire file:

import React, {useEffect, useRef, useState} from 'react';
import {requestAllLocations} from '../api/requests';
import {createBusinessFromAPI} from '../model/BusinessCreator';

export default (isScreenFocused, locationsCallback) => {

    const [businessLocations, setBusinessLocations] = useState([]);
    const [error, setError] = useState(null);
    const [render, setRender] = useState(false);

    const fetching = useRef(false);

    useEffect(() => {
        setTimeout(() => {
            setRender(!render);
        }, 20000);
    }, [isScreenFocused, render]);

    useEffect(() => {

        const searchForLocations = async () => {

            fetching.current = true;

            await requestAllLocations()
                .then((locations) => {

                    const results = locations.map(loc => {
                        return createBusinessFromAPI(loc);
                    });

                    setBusinessLocations(results);
                    locationsCallback(results);

                    fetching.current = false;

                }).catch((error) => {
                    fetching.current = false;
                    throw error;
                });
        };

        if (!fetching.current) {
            searchForLocations().catch(error => setError(error));
        }

    }, [isScreenFocused, render]);

    return [businessLocations, error];
};