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>
);
}
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.
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.
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.
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 familiarcomponentDidMount
andcomponentWillUnmount
mental model, there are usually better solutions to avoid re-running effects too often. Also, don’t forget that React defers runninguseEffect
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 oureslint-plugin-react-hooks
package. It warns when dependencies are specified incorrectly and suggests a fix.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With