fix(ui): remove setSearchParams from useEffect deps to break infinite render loop#2860
Conversation
… render loop React Router's setSearchParams is not referentially stable — it depends on searchParams in its useCallback deps, so it's recreated on every URL change (remix-run/react-router#9991). This caused the values→url sync effect to fire on every URL change (not just when form values changed), writing stale Formik values back to the URL before the url→values effect could sync them, creating an infinite ping-pong cycle. The fix excludes setSearchParams from the dependency array since it doesn't need to be a reactive trigger — only value changes should drive form→URL writes.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
WalkthroughRemoved Changes
🚥 Pre-merge checks | ✅ 3 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
src/components/Forms/FormikFilterForm.tsx (1)
101-102: Good fix — consider a brief rationale comment for future maintainers.The removal of
setSearchParamsfrom the dependency array is correct. Since the effect uses the functional updater form (setSearchParams((currentParams) => …)), it always receives the latest params and doesn't close over a stale reference. This cleanly breaks the infinite loop caused by React Router's referentially unstablesetSearchParams.A short comment explaining why the dep is omitted (beyond just silencing the lint) would help future readers who might be tempted to "fix" the suppression:
Suggested comment
- // eslint-disable-next-line react-hooks/exhaustive-deps - }, [filterFields, paramsToReset, values]); + // setSearchParams is intentionally omitted: it is not referentially stable + // (react-router#9991) and the functional updater form already provides the + // latest params, so including it would cause an infinite render loop. + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [filterFields, paramsToReset, values]);
React Router's setSearchParams is not referentially stable — it
depends on searchParams in its useCallback deps, so it's recreated
on every URL change
resolves: #2859
Reverts: 3cbeafb#diff-cc88bafad38be29277f5b003d393d46464e4e547f6effda1ba28978ff8d3f0b8L33-L36