DIGIT Frontend React 19 Upgrade

Overview

This page provides a comprehensive guide for the major upgrade of the DIGIT Frontend Health Micro-UI application. The upgrade covers multiple significant changes, including React version, build system, routing, and data fetching libraries.

Upgrade Summary Table

Library/Tool
Before
After

React

17.0.2

19.0.0

React DOM

17.0.2

19.0.0

React Router DOM

5.3.0

6.25.1

React Query

3.6.1

@tanstack/react-query 5.62.16

React Hook Form

6.15.8

7.52.2

React i18next

11.16.2

15.0.0

React Redux

7.x

9.2.0

Build System

microbundle-crl / react-scripts

Webpack 5


Migration Summary

What Changed

  1. Build System: Migrated from microbundle-crl and react-scripts to a custom Webpack 5 configuration

  2. React Version: Major upgrade from React 17 to React 19 (skipping React 18)

  3. Routing: Complete rewrite from React Router v5 to v6 syntax

  4. Data Fetching: Migration from react-query v3 to @tanstack/react-query v5

  5. Form Handling: Updated react-hook-form from v6 to v7

  6. Internationalization: Updated react-i18next from v11 to v15


Build System Migration

From microbundle-crl to Webpack 5

Why the Change?

  • Better control over build configuration

  • Improved hot module replacement (HMR)

  • Better code splitting and optimisation

  • Custom proxy configuration for development

  • Bundle analysis capabilities

Old Setup (microbundle-crl)

New Setup (Webpack 5)

Webpack Configuration Structure


React 17 to React 19 Migration

Breaking Changes

1. Rendering API (Critical)

React 17 (Before)

React 19 (After)

2. forwardRef Removal

React 17 (Before)

React 19 (After)

3. Context Provider Syntax

React 17 (Before)

React 19 (After)

4. defaultProps Removed

React 17 (Before)

React 19 (After)

5. Automatic Batching

circle-info

Note: React 19 automatically batches all state updates, even in setTimeout, promises, and native event handlers.

6. New Hooks in React 19


React Router v5 to v6 Migration

Major Syntax Changes

1. Switch → Routes

v5 (Before)

v6 (After)

2. useHistory → useNavigate

v5 (Before)

v6 (After)

3. Redirect → Navigate

v5 (Before)

v6 (After)

4. Route Props → Hooks

v5 (Before)

v6 (After)

5. Nested Routes

v5 (Before)

v6 (After)

v5 (Before)

v6 (After)

Quick Reference Table

v5
v6

<Switch>

<Routes>

<Route component={X}>

<Route element={<X />}>

<Route render={() => ...}>

<Route element={...}>

<Redirect to="/">

<Navigate to="/" replace>

useHistory()

useNavigate()

history.push(path)

navigate(path)

history.replace(path)

navigate(path, { replace: true })

history.goBack()

navigate(-1)

useRouteMatch()

useMatch()

match.params

useParams()


React Query to TanStack Query v5 Migration

Package Change

Old (v3)

New (v5)

Import Changes

v3 (Before)

v5 (After)

1. useQuery Signature Change

v3 (Before)

v5 (After)

2. useMutation Signature Change

v3 (Before)

v5 (After)

3. Status Flags Renamed

Important: isLoading is now isPending

v3 (Before)

v5 (After)

4. Query Invalidation

v3 (Before)

v5 (After)

Quick Reference Table

v3
v5

useQuery(key, fn, options)

useQuery({ queryKey, queryFn, ...options })

useMutation(fn, options)

useMutation({ mutationFn, ...options })

isLoading

isPending

isIdle

Check status === 'pending' && fetchStatus === 'idle'

invalidateQueries('key')

invalidateQueries({ queryKey: ['key'] })

refetchQueries('key')

refetchQueries({ queryKey: ['key'] })

setQueryData('key', data)

setQueryData(['key'], data)


Other Library Updates

React Hook Form (v6 → v7)

Register Method Change

v6 (Before)

v7 (After)

React i18next (v11 → v15)

React Redux (v7 → v9)

  • Better React 19 compatibility

  • Improved TypeScript support

  • Same useSelector and useDispatch API


Challenges Faced

1. Peer Dependency Conflicts

Problem: Multiple libraries had peer dependencies on different React versions.

Solution: Use resolutions in package.json

2. Build System Complexity

Problem: microbundle-crl didn't support the advanced features needed.

Solution: Custom Webpack 5 configuration with proper code splitting and HMR.

3. React Router Complete Rewrite

Problem: v5 to v6 required rewriting all routing logic.

Solution: Systematic migration using the reference tables in this document.

4. React Query Breaking Changes

Problem: Complete API signature change from v3 to v5.

Solution: Search and replace using regex patterns, then manual review.

5. forwardRef Throughout Codebase

Problem: Many components used the forwardRef pattern.

Solution: Convert all forwardRef to ref as a prop pattern.

6. Automatic Batching Side Effects

Problem: Code that relied on synchronous state updates broke.

Solution: Use flushSync for critical synchronous updates:


Troubleshooting Guide

Error: "ReactDOM.render is no longer supported"

Error: "useHistory is not exported"

Error: "Switch is not exported"

Error: "useQuery expects object"

Error: "isLoading is undefined"

Peer Dependency Warnings

Webpack Build Fails


Upgrade Roadmap

Phase 1: Preparation

  • Create a feature branch for the upgrade

  • Audit all dependencies and their React 19 compatibility

  • Document current application behaviour

  • Set up comprehensive test coverage

  • Back up the current configuration

Phase 2: Build System Migration

  • Create webpack.common.js

  • Create webpack.dev.js

  • Create webpack.prod.js

  • Configure Babel for React 19

  • Set up development server with proxy

  • Configure code splitting and optimization

  • Test build process

Phase 3: Core Dependencies Update

  • Update React and React DOM to 19.0.0

  • Update entry point to use createRoot

  • Add resolutions for React version

  • Fix initial compilation errors

  • Test basic rendering

Phase 4: React Router Migration

  • Update react-router-dom to v6

  • Replace Switch with Routes

  • Replace the Route component prop with the element

  • Replace Redirect with Navigate

  • Replace useHistory with useNavigate

  • Update nested routes to use Outlet

  • Update NavLink syntax

  • Test all navigation flows

Phase 5: React Query Migration

  • Install @tanstack/react-query v5

  • Update all imports

  • Convert useQuery to object syntax

  • Convert useMutation to object syntax

  • Update invalidateQueries calls

  • Replace isLoading with isPending

  • Test all data fetching

Phase 6: Other Libraries

  • Update react-hook-form to v7

  • Update register syntax

  • Update react-i18next

  • Update react-redux

  • Update other dependencies

Phase 7: Component Updates

  • Remove forwardRef usage

  • Update defaultProps to default parameters

  • Update Context.Provider syntax

  • Add proper cleanup to useEffect hooks

  • Fix any batching-related issues

Phase 8: Testing & QA

  • Run full test suite

  • Fix failing tests

  • Manual testing of all features

  • Performance profiling

  • Browser compatibility testing

  • Fix any remaining issues

Phase 9: Deployment

  • Code review

  • Staging deployment

  • Production deployment

  • Monitor for errors

  • Update documentation


References

Last updated

Was this helpful?