Reputation: 59
I can't seem to find an answer to this despite trying different things. I keep getting the error:
Line 18:5: React Hook useEffect has a missing dependency: 'execute'. Either include it or remove the dependency array react-hooks/exhaustive-deps
printWarnings
on this file:
import {useEffect, useState} from 'react'
export const createEffect = (fs, dependency) => {
const[data, setData] = useState({})
const execute = () => (
fs().then(res => {
setData(res)
}).catch(err => {
// do some magic
})
)
useEffect(() => {
execute()
const interval = setInterval(execute, 15000)
return(() => clearInterval(interval))
}, [dependency])
return(data)
}
The TLDR is I need to make a fetch request to a specific API function defined by fs()
either every 15 seconds or when some global state changes, defined by dependency
. I also want to capture the data and any errors hence why I'm wrapping the fs()
around with a couple of then()
and catch()
blocks.
The following code gives me the warning at the top when I execute it inside my functional component:
import createEffect from './components/createEffect'
~~~
let api = new api('http://localhost:8080/v1');
const[status, updateStatus] = useState(true);
const summary = createEffect(api.getSummary, status)
Any idea how I can fix this? I'm new to React useEffect and not 100% if this is the right way to go about doing something like this? Specifying execute
as a dependency inside my useEffect call causes the app to constantly re-render. I'm running execute()
before calling setInterval()
because I want the query to run every 15 seconds AND when the component first renders.
For more context: I'm making a dashboard as a sample project and want to query multiple api endpoints every 15 seconds or immediately when some global state changes. If the global state does change, I want to reset my HTTP polling from whatever time that is left back to 15 seconds.
Upvotes: 0
Views: 1137
Reputation: 2522
The linting error is very straight just says exactly what you need to do, either leaving the dependency array of useEffect
as empty, or add the execute
function into it.
Basically, because you access the execute
function inside the effect callback, and as it's created within the same scope as the effect, React requires it to be a dependency.
To resolve the problem with continuous re-rerendering, you need to make your execute function a memoized function by using useCallback
Solving it should be as simple as:
const execute = useCallback(() => (
fs().then(res => {
setData(res)
}).catch(err => {
// do some magic
})
), [setData]);
useEffect(() => {
execute()
const interval = setInterval(execute, 15000)
return(() => clearInterval(interval))
}, [execute])
Upvotes: 3
Reputation: 2202
I think you can add execute
as a dependency, since the function definition itself isn't changing. Just debug if the component is re-rendering after every call. I think they shouldn't.
Upvotes: 0