Dovtutis
Dovtutis

Reputation: 125

useEffect with time interval runs twice each time

Hello I have a simple application where I fetch data every 3 seconds by using useEffect with time interval. Everything works as needed buy by logging in the console I see that my useEffect works twice, it calls fetchData function twice almost at the same time. I think I am missing something in my code. Thank you for your help!

       useEffect(() => {
        const interval = setInterval(() => {
          fetchChatData();
        }, 3000);
        return () => clearInterval(interval);
      });

  const fetchChatData = () => {
    setError(null);

    async function fetchData() {
      const request = await axios.get(
        "https://api.jsonbin.io/v3/b/60e6d8a81f8e4a7f2a",
        {
          headers: {
            "Content-Type": "application/json",
            "X-Master-Key":
              "$2b$10$OSaM64SeFaeWQMwrro08kuypgEG7Q",
          },
        }
      );
      const responseData = await request.data;
      chatCtx.setChatData(responseData.record);
    }

    fetchData();
    fetchData().catch((error) => {
      setError(error.response.data.message);
    });
  };

Upvotes: 0

Views: 1128

Answers (3)

Giovanni Esposito
Giovanni Esposito

Reputation: 11156

I can't see all your component's code but an useEffect as is runs on every component's re-render. Juat ad an empty array as useEffect's second parameter and it will run just first component's render. Something like:

      useEffect(() => {
        const interval = setInterval(() => {
          fetchChatData();
        }, 3000);
        return () => clearInterval(interval);
      }, []);

Upvotes: 1

allkenang
allkenang

Reputation: 1645

I would use 2 hooks. The first hook executes when the component loads and therefore it's dependency array is set to an empty array []

useEffect(()=>{
   // invoke web service to read data into the chatData state variable 
   // when the component loads for the first time
},[])

Then I have another useEffect hook that has the chatData state variable set into it's dependency array. This hook will wait for 3-seconds before invoking the web service.

useEffect(()=>{
   // wait 3 seconds
   // invoke web service to read data into the chatData state variable
},[chatData])

Each time the web service is invoked in the 2nd hook, the chatData dependency in the hook will change and this in turn will cause this hook to fire again indefinitely.

Upvotes: 1

TheRakeshPurohit
TheRakeshPurohit

Reputation: 551

You are calling fetchData function twice out of useEffect that causes the second API call.

Remove

fetchData();

before

fetchData().catch((error) => {
      setError(error.response.data.message);
    });

Upvotes: 1

Related Questions