0

I have a funtion inside a useEffect hook that requests some data to my server:

useEffect(() => {
  const reqFn = async () => {
    // req code...
    setState(req result)
  }
  return reqfn()
},[setState])

Also, I need to run this function when a user clicks on a button to request a different data (reqFn uses a useState value as a prop for the server request).

I've tried taking the reqFn() outside the useEffect, but this makes running reqFn in a loop. How can I achieve this?

ask4you
  • 768
  • 3
  • 14
  • Why not calling this function in first render in useEffect without state callback and rest of updates with onClick of your button? – Evren May 15 '22 at 20:49
  • 2
    The return inside useEffect is for when the Component is being unmounted, the way to clean up everything to avoid unwanted process to be executed for nothing. So you might just call `reqFn()` alone with no return. And also, it would be better to put the function outside to be able to access it with `onClick` event, and even better on a `React.useCallback` outside to save the function for future rendering. – KeitelDOG May 15 '22 at 21:01
  • Oh, @KeitelDOG ,I didn't know the return is for when the Component is being unmounted. Tried, as you said, putting the function outside and I left the useEffect whithout the return and the `reqFn` dependecy. Now it runs ok. I don't understand how to use the `useCallback` hook, even though I've read of it, and I dont find the difference with the `useMemo` hook. Could yo give me more info about how to use It in this case? – ask4you May 15 '22 at 21:47
  • 1
    @ask4you and also, the return inside `useEffect` must be function like `return () => { ... };`. That function will be called before unmounting component. Returning the result of the call like `return reqFn()` in your case would return `undefined` since the function `reqFn` returns nothing when called. So this would do nothing when unmounting anyway. – KeitelDOG May 15 '22 at 23:03

1 Answers1

3

As I see from your question you need api data in the first render and then you are handling updates with just click. So you can use useEffect without state callback and handle the rest with onClick

const reqFn = async () => {
    // req code...
    setState(req result)
}

useEffect(() => {
  reqfn()
},[])

<>
...
//Rest of your component
<button onClick={reqFn}>Click</button>
...
</>
Evren
  • 4,147
  • 1
  • 9
  • 16
  • That's right, at first render I need some API data, and when user clicks the button I need to do the same request but with a diferent value. But If I put the function outside, I get the warning `React Hook useEffect has a missing dependency: 'reqFn'`; although It runs ok, but If I add the reqFn as a dependecy, it runs in a loop. Is ok if I leave the useEffect without the `reqFn` dependency? Why does It run in a loop if I add it? – ask4you May 15 '22 at 21:41
  • For this warning there are many solutions, have a look https://stackoverflow.com/questions/55840294/how-to-fix-missing-dependency-warning-when-using-useeffect-react-hook . If my answer resolved your problem, could you please choose as accepted answer? @ask4you – Evren May 15 '22 at 21:47
  • 1
    @ask4you it runs in a loop if you forget to add the empty dependencies array `[]` as second argument in `useEffect`. `useCallback` is the same way as `useEffect`, with dependencies array. Like `const reqFn = React.useCallback(async () => { ... }, [...]);` The points are for function codes and dependencies you use inside. This way it you won't get warning about performance for `useCallback` suggestion. – KeitelDOG May 15 '22 at 22:59