replace useState with useEffect in useBreakpoint hook to prevent memory leak#851
replace useState with useEffect in useBreakpoint hook to prevent memory leak#851divyansh-cyber wants to merge 1 commit intoaccordproject:mainfrom
Conversation
…ry leak Signed-off-by: Divyansh Rai <140232173+divyansh-cyber@users.noreply.github.com>
✅ Deploy Preview for ap-template-playground ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
There was a problem hiding this comment.
Pull request overview
Fixes a lifecycle bug in the custom useBreakpoint hook used by Navbar by moving the resize event listener setup/cleanup into useEffect, preventing leaked listeners across remounts (notably under React Strict Mode).
Changes:
- Import
useEffectand replace the prioruseStateinitializer side-effect with auseEffect(..., [])subscription. - Ensure the
resizelistener is properly removed on unmount via the effect cleanup.
| const useBreakpoint = () => { | ||
| const [screenSize, setScreenSize] = useState({ | ||
| sm: false, | ||
| md: false, | ||
| lg: false, | ||
| xl: false, | ||
| }); | ||
|
|
||
| useState(() => { | ||
| useEffect(() => { | ||
| const checkSize = () => { | ||
| setScreenSize({ | ||
| sm: window.innerWidth >= 640, | ||
| md: window.innerWidth >= 768, | ||
| lg: window.innerWidth >= 1024, | ||
| xl: window.innerWidth >= 1280, | ||
| }); | ||
| }; | ||
|
|
||
| checkSize(); | ||
| window.addEventListener('resize', checkSize); | ||
| return () => window.removeEventListener('resize', checkSize); | ||
| }); | ||
| }, []); |
There was a problem hiding this comment.
useBreakpoint now initializes screenSize to all false and only updates it in useEffect, which means the navbar can briefly render the “mobile” layout on desktop before the effect runs (layout shift/flash). Consider initializing state from window.innerWidth in the useState initializer (or using useLayoutEffect) so the first render matches the current viewport, and keep the effect only for the resize subscription/cleanup.
|
This PR is stale because it has been open 15 days with no activity. Remove stale label or comment or this will be closed in 10 days. |
Fixes #850
Description
The custom useBreakpoint hook in Navbar.tsx was incorrectly using
useStateto register awindow.addEventListener('resize', ...)side-effect. React'suseStateinitializer runs once but silently discards any return value, meaning the cleanup function (removeEventListener) was never called.This caused:
resizelisteners accumulated on every component remount (e.g., route navigation).Changes Made
useStatewithuseEffect(+ empty[]deps) in the useBreakpoint hookBefore (Bug)
After (Fix)
How to Test
/and/learn/intromultiple times.Checklist