useEffect call recursively when add functional props as dependency
See original GitHub issueWhat is the current behavior?
- Define a component with useEffect and useState
const [style, setStyle] = useState({ color: "#000000" });
const [signature, setSignature] = useState("Your Name");
useEffect(() => {
html2canvas(document.getElementById("signature-container")).then(
canvasEl => {
onChange(canvasEl.toDataURL());
},
);
}, [signature, style]);
- Pass onChange function as props
<Text onChange={handleChange} />
It’s warn need to add onChange
prop into dependency array of useEffect
but If I add onChange
prop into the array, useEffect
call recursively
What is the expected behavior? Don’t need to warn if user don’t pass function props as dependency
Issue Analytics
- State:
- Created 4 years ago
- Reactions:3
- Comments:10 (5 by maintainers)
Top Results From Across the Web
Recursive/cyclic call to useEffect - React - Stack Overflow
I have a component that triggers the useEffect if it receives an update from the parent element. So it calls a function that...
Read more >Understanding Dependencies in useEffect | Bits and Pieces
A deep dive into the dependencies array in React.useEffect(). What causes stale values from previous renders in React.
Read more >Avoiding recursive useEffect hooks in React - Jack Franklin
Therefore we can lose it from our useEffect dependencies array, meaning that useEffect won't rerun when it changes!
Read more >How the useEffect Hook Works (with Examples) - Dave Ceddia
Run useEffect When a Prop Changes useEffect can trigger on any of them. In this example, the PropChangeWatch component is receiving 2 props...
Read more >useMemo - React Docs
React will call your function during the initial render. On subsequent renders, React will return the same value again if the dependencies have...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
OK this is interesting. Normally you’d fix this by passing an
onChange
with a stable identity:But in your case it wouldn’t work because it’s inside Formik’s render prop callback.
I’m not sure what’s the idiomatic solution here from Formik’s point of view.
But in your case, it seems like it’s not actually important to re-run
onChange
if theonChange
function itself changes. Therefore, you can use a ref to explicitly track its latest value:And then you can all
latestOnChange.current
in the effect.https://codesandbox.io/s/l5z8z3jj3z
Was there ever a proper answer to @gaurav5430 's question? I’m wondering the same. It feels odd to ask parents to pass functions with stable identity’s as props. There’s no way to know WHEN you need to do this, and asking them to use
useCallback
everywhere don’t seem like a good idea.I, too, have a shared component library and it seems to me unfeasible to ask consumers to always pass useCallback or else have the component break. I’ve relied on the useRef hack for a while, but it comes with its own limitations. Sometimes I also just ignore the empty dependency list and be done with it.
Quick sample would be a modal component:
Is there a best practice for this, @gaearon ?