Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React hooks fetch won't stop fetching

I'm trying to rebuild some class components I have as functional components using React hooks to do the fetch.

I can fetch the data, this is fine, but it's calling to my API every few milliseconds, I just want it to fetch the data and stop as it would have in the class component with componentDidMount.

I think I can see why it's doing it (the fetchData() inside the function means it will just keep calling itself) but I'm not sure how to fix it.

I tried adding a setInterval, changing the order, and moving the fetchData() outside the function (the component wouldn't render because it was then undefined).

const MyFunction = () => {

const [apiResponse,setApiResponse] = useState({})

  async function fetchData() {

    const res = await fetch(`http://localhost:9000/example`,{
      method: 'POST',
      mode: 'cors',
      body: JSON.stringify({date: '20190707'}),
      headers: {'content-type': 'application/json',
      credentials: 'include'
    }
    })
  res
  .json()
  .then(res => setApiResponse(res))
  }

useEffect(() => {

  fetchData();

});


var queryResult = apiResponse['units']


return (
  <React.Fragment>  
    <CardHeader color={"info"} stats icon>
    <CardIcon color={"info"}>
    <Icon>{"trending_up"}</Icon>
    </CardIcon>
    <p className={''}>Drop In</p>
      <h3 className={''}>
        {queryResult} <small>Units</small>
      </h3>
    </CardHeader>
    <CardFooter ></CardFooter>
  </React.Fragment>        
);

}
like image 754
Lawrence Ferguson Avatar asked Jul 07 '19 21:07

Lawrence Ferguson


People also ask

How do I stop fetching in React?

Using AbortController to cancel fetch AbortController contains an abort method. It also contains a signal property that can be passed to fetch . When AbortController. abort is called, the fetch request is cancelled.

How do you fix React Hooks exhaustive DEPS?

The "react-hooks/exhaustive-deps" rule warns us when we have a missing dependency in an effect hook. To get rid of the warning, move the function or variable declaration inside of the useEffect hook, memoize arrays and objects that change on every render or disable the rule.

Are React Hooks cached?

To keep the CPU loads minimal by avoiding unnecessary loads, React provides two Hooks that help in memoization. The Hooks follow a process in which the results are cached in memory and returned without re-computation when we get the same input.


1 Answers

Try adding an empty array at the end of your useEffect:

useEffect(() => {

  fetchData();

}, []);

React Docs: https://reactjs.org/docs/hooks-effect.html

Note

If you use this optimization, make sure the array includes all values from the component scope (such as props and state) that change over time and that are used by the effect. Otherwise, your code will reference stale values from previous renders. Learn more about how to deal with functions and what to do when the array changes too often.

If you want to run an effect and clean it up only once (on mount and unmount), you can pass an empty array ([]) as a second argument. This tells React that your effect doesn’t depend on any values from props or state, so it never needs to re-run. This isn’t handled as a special case — it follows directly from how the dependencies array always works.

If you pass an empty array ([]), the props and state inside the effect will always have their initial values. While passing [] as the second argument is closer to the familiar componentDidMount and componentWillUnmount mental model, there are usually better solutions to avoid re-running effects too often. Also, don’t forget that React defers running useEffect until after the browser has painted, so doing extra work is less of a problem.

We recommend using the exhaustive-deps rule as part of our eslint-plugin-react-hooks package. It warns when dependencies are specified incorrectly and suggests a fix.

like image 182
Ion Avatar answered Sep 18 '22 03:09

Ion