I have found a few questions related to this on stackoverflow, but nothing that satisfies a use-case which I have very regularly while using useEffect
. Let's say I have some code like this:
const ApiViewer = (props) => {
const [result, setResult] = useState('')
useEffect(async () => {
setResult(await callApi(props.valueThatWillChangeButIOnlyCareAboutItsInitialValue))
}, [])
return <div>{result}</div>
}
The exhaustive-deps
rule will throw, asking me to put props.valueThatWillChangeButIOnlyCareAboutItsInitialValue
in the dependency array. I don't want to do this as I only want the initial value. I may use that prop in a separate effect somewhere.
I can't think of another way to write this either.
I also have the problem that other people seem to have, i.e. using functions/etc that I know will never change. I don't want to add them to this array, seems very dumb.
Dan Abramov said that Usually disabling it is a mistake and will significantly bite you later. I've been using it this way for years and I've seen no issues until this rule started popping up in a new project.
Am I using React completely wrong?
Treating "exhaustive deps" as the true rule that it is will ensure components update as expected.
If you want to ignore updates to a given prop you can clarify that by using a useRef
. You won't get any warnings inside a useEffect
because the base object returned from useRef
never changes. Using an initial
prefix will make this obvious to the next developer as well.
const ApiViewer = (props) => {
const [result, setResult] = useState('')
const initialValueThatWillChangeRef = useRef(props.valueThatWillChange);
useEffect(async () => {
setResult(await callApi(initialValueThatWillChangeRef.current))
}, [])
return <div>{result}</div>
}
You can construct examples where everything works as expected by ignoring the "exhaustive deps" rule, but you will eventually run into a nuanced case that breaks for reasons that are difficult to debug.