-1

I have a fetch query that is running multiple times. I am using react JS. Why is this happening? How can I prevent the query from running multiple times?

Here is my code

const MyComponent = () => {
  const [tokenslist, setTokensList] = useState([])
    
  fetch("http://localhost:81/getTokensList")
   .then(response => response.json())
   .then(data => {
       setTokensList(data);
       console.log("TOKENS", tokenlist);
       query(tokenslist)
   });

   ...
}
Othmani Ali
  • 203
  • 1
  • 5
chackerian
  • 1,301
  • 2
  • 15
  • 29
  • 1
    Without seeing the relevant code it's impossible to say. – Alejandro Apr 26 '22 at 21:53
  • 1
    Its a normal fetch request that is running multiple times for some reason – chackerian Apr 26 '22 at 21:56
  • 1
    Post the whole relevant code. That line, all by itself, cannot ever tell anyone why it runs multiple times. Context of where is it and who calls it is important. So far the only reasonable answer I can give is "you called it multiple times", which is obviously useless. – Alejandro Apr 26 '22 at 22:08

1 Answers1

2

Why does it run many times?

It is because whenever you set to a state like using setTokensList in your example, this will tell React to execute all the javascript code in your component again starting from top to bottom in the same order.

To avoid executing some of your code every time but only upon some variables changes, you should use useCalback or useMemo React hooks.

In your case you have a side effect code like loading data from a remote endpoint. In this case it is better to be done in the componentDidMount lifecycle hook. Because your component will execute your code in this hook only once after the first render and not multiple times where you don't want to in your situation.

If you are using react hooks, you can achieve that by placing your code in the useEffect hook as follows:

const [tokenslist, setTokensList] = useState([])

useEffect(()=> {
 fetch("http://localhost:81/getTokensList")
   .then(response => response.json())
   .then(data => { 
      setTokensList(data);
      console.log("TOKENS", data);
      query(data);
    });
}, []);
Othmani Ali
  • 203
  • 1
  • 5
  • I have tried using this hook and it doesn't set the tokenslist variable properly. – chackerian Apr 26 '22 at 22:59
  • then please provide more details about your code so that I can help you better – Othmani Ali Apr 26 '22 at 23:03
  • Ok, do you know why it would run so many times in React? I don't understand this behavior. – chackerian Apr 26 '22 at 23:12
  • Now I think I have the complete picture: you are setting the tokenlist in the second 'then' which is totally fine but React won't give you the updated 'tokenslist' right away after you set it there. It has to finish executing all the code in that callback. But also you wouldn't have a chance to get the updated value in the useEffect because it will run only once. So the only way to get it is to use the 'data' value which is, in the end, the updated value you are looking for. I've adjusted the answer to use data instead of tokenslist and now your code should run correctly. – Othmani Ali Apr 27 '22 at 00:02
  • Why does it run so many times? it is because whenever you set to a state like using setTokensList, this will tell React to execute all the javascript code in your component again starting from top to bottom in the same order. But there is some ways to tell React to not execute some code everytime and the useEffect hook is some of the ways to do that. – Othmani Ali Apr 27 '22 at 00:02