0

I'm requesting API data through axios using RapidAPI's Apis.

I followed all the documentations provided in RapidAPI with a relatively simple code. However, when I log the values, it keeps repeatedly requesting data over and over and this in turn hikes up my requests from RapidAPI and uses a lot of resources and money. I can't figure out how to only retrieve the values ONCE. Here are my codes.

My React .tsx file

const [sportsData, setSportsData] = useState() 
const fetchSportsData = () => {
axios
  .request(testApi)
  .then((response) => {
    setSportsData(response.data)
  })
  .catch((error) => {
    console.log(error)
  })
} 
fetchSportsData()
console.log(sportsData)

My Api File

export const testApi = {
method: 'GET',
url: 'https://api-football-v1.p.rapidapi.com/v3/timezone',
 headers: {
 'X-RapidAPI-Key': '-------removed on purpose ---------',
 'X-RapidAPI-Host': 'api-football-v1.p.rapidapi.com'
 }
}

I am just setting the data using useState but it seems to repeatedly rerender whenever a value is stored. I've tried many roundabout ways but it seems to repeatedly request over and over again. Has anyone used API's from RapidAPI before?

rt10
  • 25
  • 4
  • 1
    You put `fetchSportsData()` call inside the component as is, not inside useEffect or anything. So, every time you change the state - component's function code is reexecuded. Completely. Meaning even this `fetchSportsData()` is called. Which then sets the state, forcing a component to rerender and etc. – Sergey Sosunov Feb 04 '23 at 14:28
  • Does this answer your question? [How to call loading function with React useEffect only once](https://stackoverflow.com/questions/53120972/how-to-call-loading-function-with-react-useeffect-only-once) – Sergey Sosunov Feb 04 '23 at 14:29
  • I came across the same article. I haven't given it a go yet but I'm just curious why does all the documentations say to use the method I've outlined in the question but it doesn't work and constantly re-renders? Are they outdated or something? – rt10 Feb 07 '23 at 16:30
  • Hard to say why it doesnt work for you without seeing your code, and no, nothing is really outdated, initially we had react class components, then react functional components appeared but they still share same concepts. And in your question you meantioned useState, which is.. well Im not sure if i need to re-write react docs here. Fix your code by wrapping axios request inside useEffect with empty dependencies array `[]` as a second parameter and if it will not work for you - feel free to edit your question with new details and code. Error is not due to useState, but due to axios in body. – Sergey Sosunov Feb 07 '23 at 16:41
  • @SergeySosunov the useEffect method works, and so far it's the only one that can retrieve API calls with axios correctly. However it still renders twice on every load, but this only happens in dev mode, to reduce cost on development we can use useRef to make sure the code in useEffect runs only once. Thanks for the input. I still don't understand what's the issue with useState. – rt10 Feb 10 '23 at 06:53

1 Answers1

0

While I don't know why useState will still repeatedly retrieve API data with axios, this is a workaround as commented by Sergey Sosunov.

On the React File

const [sportsData, setSportsData] = useState()


const fetchSportsData = () => {
axios.request(testApi).then((response) => {
    setSportsData(response.data)
  })
  .catch((error) => {
    console.log(error)
  })
}

useEffect(()=> {
  fetchSportsData()
},[])

On dev mode, the useEffect will run twice on load and depending on your API provider, this may mean calling the API twice on every load which may double your costs unnecessarily, this only happens in development mode as outlined in react documentation, what you can do is include a useRef variable.

const firstRender = useRef(false)

useEffect(()=>{ 
  if (firstRender.current) {
    fetchSportsData()
  } else {
    firstRender.current = true;
  }
},[])

Remember that this code may not execute perfectly when in production as useEffect is only run once and the above code needs it to run twice in order to change the state of firstRender to true before retrieving the API call. This is just to help you lower your development costs.

rt10
  • 25
  • 4