What happened?
What happened?
places-map.tsx hydrates URL state by calling setFilters and setFocusId
directly inside a useEffect body on mount:
This triggers a second render immediately after the first — the component
mounts with empty state, then re-renders with the URL values.
ESLint (react-hooks/set-state-in-effect) flags both setState calls.
React.useEffect(() => {
const state = parseMapState(window.location.search);
setFilters({ types: state.types, cities: state.cities });
setFocusId(state.placeId);
hydrated.current = true;
}, []);
What did you expect to happen?
State should be derived from the URL on the first render, not patched in
after it.
Error reported on lines 47–48:
Calling setState synchronously within an effect can trigger cascading renders
Proposed fix
Use lazy useState initialisers so the URL is parsed once at mount, with no
effect needed:
const [filters, setFilters] = React.useState<PlaceFilters>(() => {
if (typeof window === "undefined") return { types: [], cities: [] };
const state = parseMapState(window.location.search);
return { types: state.types, cities: state.cities };
});
const [focusId, setFocusId] = React.useState<string | null>(() => {
if (typeof window === "undefined") return null;
return parseMapState(window.location.search).placeId ?? null;
});
Steps to reproduce
Run ESLint on src/components/map/places-map.tsx:
node_modules/.bin/eslint src/components/map/places-map.tsx
Browser and OS
No response
Screenshots or console logs (optional)
No response
Checklist
What happened?
What happened?
places-map.tsxhydrates URL state by callingsetFiltersandsetFocusIddirectly inside a
useEffectbody on mount:This triggers a second render immediately after the first — the component
mounts with empty state, then re-renders with the URL values.
ESLint (react-hooks/set-state-in-effect) flags both setState calls.
What did you expect to happen?
State should be derived from the URL on the first render, not patched in
after it.
Error reported on lines 47–48:
Calling setState synchronously within an effect can trigger cascading renders
Proposed fix
Use lazy useState initialisers so the URL is parsed once at mount, with no
effect needed:
Steps to reproduce
Run ESLint on src/components/map/places-map.tsx:
node_modules/.bin/eslint src/components/map/places-map.tsx
Browser and OS
No response
Screenshots or console logs (optional)
No response
Checklist