Darius
Darius

Reputation: 7

My Reactjs program keeps executing the useEffect hook continuously, whilst I want it to execute only once

import React, { useEffect } from "react";
import useHttp from "./hooks/use-http";

export default function App() {
  const getReq = async () => {
    const response = await fetch(
      "" // assume this to be a random link fetching data
    );
    const responseData = await response.json();
    return responseData;
  };

  const { sendRequest, data } = useHttp(getReq);

  useEffect(() => {
    sendRequest();
  }, []);

  console.log(data);

  return <div></div>;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

import React, { useState } from "react";

const useHttp = (getReq) => {
  const [data, setData] = useState([]);
  const sendRequest = async () => {
    try {
      const data = await getReq();
      setData(data);
    } catch (error) {}
  };

  return {
    sendRequest,
    data,
  };
};

export default useHttp;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

In the useEffect hook, if I remove sendRequest as a dependency (as done in this example), I don't get any problems and the hook only runs once.

But, if I add it as a dependency (for good practice purposes), the hook runs continuously and I get recurring console.log statements. Could someone please explain why this is happening?

Upvotes: 0

Views: 291

Answers (1)

Giorgi Moniava
Giorgi Moniava

Reputation: 28654

But, if I add it as a dependency (for good practice purposes), the hook runs continuously and I get recurring console.log statements. Could someone please explain why this is happening?

Because sendRequest is a function which is re created each time the component is re-rendered, hence, it is different on each render. Because of that, when it is listed as a dependency, useEffect re-runs. Consider using useCallback and wrapping sendRequest using it.


Consider re-rendering of a component same as the function being re-invoked, hence you are creating all the variables or functions inside it from scratch (except cases when React takes care to retain value of your variable across re-renders; this happens with variables from state for example).

Upvotes: 1

Related Questions