beauchette
beauchette

Reputation: 1126

Best practises React hooks HTTP loading

I recently started another project with react, as I had a little time to fiddle around, I used functional components with hooks. I had no problem whatsoever, there's just one thing I'm not sure I use correctly, here is an example :

function MyComponent() {
  const [data, setData] = useState([]);
  const [dataLoaded, setDataLoaded] = useState(false);

  var getDataFromHTTP = async () { ... }

  var loadData = async () => {
    if (!dataLoaded) {
      setDataLoaded(true);
      setData(await getDataFromHTTP());
    }
  }

  loadData();

  return( ... );
}

If I like how everything is done, I suppose it's dirty to use loadData(); like in the preceding example, and I tried to useEffect with something like this :

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

but then I got a warning like "loadData should be a dependency of useEffect". If I omit the the second argument to useEffect, it looks like it's the same as putting it directly in MyComponent. So basically, my question, in this example what is the best practise to load data once when the component is mounted ? and of course, when props/state change, what is the best practise to reload it if needed ?

EDIT: The warning I have with useEffect is :

[Warning] ./src/list/main.js (1.chunk.js, line 25568)
Line 53:  React Hook useEffect has a missing dependency: 'loadData'. Either include it or remove the dependency array  react-hooks/exhaustive-deps

Upvotes: 1

Views: 161

Answers (1)

Prithwee Das
Prithwee Das

Reputation: 5226

The way useEffect works is whenever something in the dependencies array change React will run that effect

useEffect(() => {
  loadData();
}, [loadData]); // <-- dependencies array

But as you have declared loadData as a normal function it will get re-assigned to a new function on every render and it will trigger the effect. Best way would be to wrap your loadData function in an useCallback hook

const loadData = useCallback(async () => {
    if (!dataLoaded) {
      setDataLoaded(true);
      setData(await getDataFromHTTP());
    }
}, [])

Upvotes: 2

Related Questions