Skip to content

Conversation

@antontranelis
Copy link
Member

@antontranelis antontranelis commented Dec 18, 2025

Update to React 19

Summary

  • Upgrade React from 18 to 19
  • Upgrade react-leaflet from 4 to 5
  • Upgrade react-leaflet-cluster from 3 to 4
  • Upgrade react-toastify from 9 to 11
  • Upgrade react-router-dom to 7

Breaking Changes Fixed

React 19 Strict Mode Changes

  • useRef requires initial value: Updated all useRef calls to provide explicit initial values (null or appropriate defaults)
  • No setState during render: Moved navigate() calls out of toast.promise render callbacks - React 19 strictly enforces no state updates during render phase

react-toastify v11 API Changes

  • Icon must return ReactNode: Updated icon callbacks to return ReactNode instead of JSX element directly

React Router 7 Changes

  • navigate() returns Promise: Added void operator where needed
  • Relative paths behavior changed: Fixed RelationsView.tsx to use absolute paths (/item/${id}) instead of relative paths

Race Condition Fixes

React 19's stricter batching and scheduling exposed race conditions in URL state synchronization:

Tag Filter Sync (UtopiaMapInner.tsx)

  • Problem: useEffect with filterTags in dependencies would re-add tags from stale URL after removal
  • Solution: Added tagsInitializedRef to only sync tags from URL on initial load, not on every state change

Layer Filter Sync (useFilter.tsx)

  • Problem: Effect could overwrite URL params set by other operations
  • Solution: Added prevVisibleLayersRef to track actual layer changes and use window.location instead of React Router's location to avoid stale state

Files Changed

File Change
useTimeout.tsx Added proper types and initial values for refs
useClusterRef.tsx Added initial value for useRef
UtopiaMapInner.tsx Fixed tag sync race condition, removed filterTags dependency
useFilter.tsx Added useRef for layer change tracking, use window.location
RelationsView.tsx Fixed relative link path to absolute
LoginPage.tsx Moved navigate() out of toast render callback
SignupPage.tsx Moved navigate() out of toast render callback
SetNewPasswordPage.tsx Refactored to use .then() instead of render callback
RequestPasswordPage.tsx Refactored to use .then() instead of render callback
Autocomplete.tsx Added initial value for useRef
ContextWrapper.tsx Updated react-toastify icon callback
UserControl.tsx Minor adjustments

Test Plan

  • Login/Signup/Password reset flows work correctly
  • Tag filtering: add and remove tags, verify URL updates persist
  • Layer filtering: toggle layers, verify URL updates persist
  • Navigation between items preserves filter state
  • Initial page load with URL params (?tags=..., ?layers=...) correctly initializes filters
  • Relations links navigate to correct item pages

@antontranelis antontranelis changed the title fix(dep-devs): update to react 19 fix(deps-dev): update to react 19 Dec 18, 2025
@antontranelis antontranelis requested a review from mahula December 19, 2025 05:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants