18 KiB
React 19 & Ant Design 6 Upgrade - Deprecation Fixes Report
Overview
This document outlines all deprecations fixed during the upgrade from React 18 to React 19 and Ant Design 5 to Ant Design 6 in the branch feature/IO-3499-React-19 compared to origin/master-AIO.
1. Core Dependency Updates
React & React DOM
- Upgraded from: React ^18.3.1 → React ^19.2.4
- Upgraded from: React DOM ^18.3.1 → React DOM ^19.2.4
- Impact: Enabled React 19 compiler optimizations and new concurrent features
Ant Design
- Upgraded from: Ant Design ^5.28.1 → ^6.2.2
- Upgraded from: @ant-design/icons ^5.6.1 → ^6.1.0
- Impact: Access to Ant Design 6 improvements and API changes
Apollo GraphQL
- @apollo/client: ^3.13.9 → ^4.1.3
- apollo-link-logger: ^2.0.1 → ^3.0.0
- graphql-ws: ^6.0.7 (added for WebSocket subscriptions)
- Impact: Major version upgrade with breaking changes to import paths and API
React Ecosystem Libraries
- react-router-dom: ^6.30.0 → ^7.13.0
- react-i18next: ^15.7.3 → ^16.5.4
- react-grid-layout: 1.3.4 → ^2.2.2
- @testing-library/react: ^16.3.1 → ^16.3.2
- styled-components: ^6.2.0 → ^6.3.8
Build Tools
- Vite: ^7.3.1 (maintained, peer dependencies updated)
- vite-plugin-babel: ^1.3.2 → ^1.4.1
- vite-plugin-node-polyfills: ^0.24.0 → ^0.25.0
- vitest: ^3.2.4 → ^4.0.18
Monitoring & Analytics
- @sentry/react: ^9.43.0 → ^10.38.0
- @sentry/cli: ^2.58.2 → ^3.1.0
- @sentry/vite-plugin: ^4.6.1 → ^4.8.0
- logrocket: ^9.0.2 → ^12.0.0
- posthog-js: ^1.315.1 → ^1.336.4
- @amplitude/analytics-browser: ^2.33.1 → ^2.34.0
Other Key Dependencies
- axios: ^1.13.2 → ^1.13.4
- env-cmd: ^10.1.0 → ^11.0.0
- i18next: ^25.7.4 → ^25.8.0
- libphonenumber-js: ^1.12.33 → ^1.12.36
- lightningcss: ^1.30.2 → ^1.31.1
- @fingerprintjs/fingerprintjs: ^4.6.1 → ^5.0.1
- @firebase/app: ^0.14.6 → ^0.14.7
- @firebase/firestore: ^4.9.3 → ^4.10.0
Infrastructure
- Node.js: 22.x → 24.x (Dockerfile updated)
2. React 19 Compiler Optimizations
Manual Memoization Removed
React 19's new compiler automatically optimizes components, making manual memoization unnecessary and potentially counterproductive.
2.1 useMemo Hook Removals
Example - Job Watchers:
// BEFORE
const jobWatchers = useMemo(() => (watcherData?.job_watchers ? [...watcherData.job_watchers] : []), [watcherData]);
// AFTER
// Do NOT clone arrays; keep referential stability for React Compiler and to reduce rerenders.
const jobWatchers = watcherData?.job_watchers ?? EMPTY_ARRAY;
Benefits:
- Eliminates unnecessary array cloning
- Maintains referential stability for React Compiler
- Reduces re-renders
- Cleaner, more readable code
Files Affected:
- Multiple kanban components
- Production board components
- Job management components
2.2 useCallback Hook Removals
Example - Card Lookup Function:
// BEFORE
const getCardByID = useCallback((data, cardId) => {
for (const lane of data.lanes) {
for (const card of lane.cards) {
// ... logic
}
}
}, [/* dependencies */]);
// AFTER
const getCardByID = (data, cardId) => {
for (const lane of data.lanes) {
for (const card of lane.cards) {
// ... logic
}
}
};
Benefits:
- React 19 compiler automatically optimizes function references
- Reduced complexity in component code
- No need to manage dependency arrays
Files Affected:
- production-board-kanban.component.jsx
- production-board-kanban.container.jsx
- Multiple board controller components
2.3 React.memo() Wrapper Removals
Example - EllipsesToolTip Component:
// BEFORE
const EllipsesToolTip = memo(({ title, children, kiosk }) => {
if (kiosk || !title) {
return <div className="ellipses no-select">{children}</div>;
}
return (
<Tooltip title={title}>
<div className="ellipses no-select">{children}</div>
</Tooltip>
);
});
EllipsesToolTip.displayName = "EllipsesToolTip";
// AFTER
function EllipsesToolTip({ title, children, kiosk }) {
if (kiosk || !title) {
return <div className="ellipses no-select">{children}</div>;
}
return (
<Tooltip title={title}>
<div className="ellipses no-select">{children}</div>
</Tooltip>
);
}
Benefits:
- Compiler handles optimization automatically
- No need for manual displayName assignment
- Standard function syntax is cleaner
Files Affected:
- production-board-kanban-card.component.jsx
- EllipsesToolTip components
- Various utility components
3. State Management Optimizations
Deep Cloning Elimination
React 19's compiler efficiently handles change detection, eliminating the need for manual deep cloning.
Example - Board Lanes State Update:
// BEFORE
setBoardLanes((prevBoardLanes) => {
const deepClonedData = cloneDeep(newBoardData);
if (!isEqual(prevBoardLanes, deepClonedData)) {
return deepClonedData;
}
return prevBoardLanes;
});
// AFTER
setBoardLanes(newBoardData);
Benefits:
- Removed lodash dependencies (
cloneDeep,isEqual) from components - Reduced memory overhead
- Faster state updates
- React 19's compiler handles change detection efficiently
4. Import Cleanup
React Import Simplifications
Example - Removed Unnecessary Hook Imports:
// BEFORE
import { useMemo, useState, useEffect, useCallback } from "react";
// AFTER
import { useState, useEffect } from "react";
Multiple files had their React imports streamlined by removing useMemo, useCallback, and memo imports that are no longer needed.
5. Apollo Client 4.x Migration
Import Path Changes
Apollo Client 4.x requires React-specific imports to come from @apollo/client/react instead of the main package.
Example - Hook Imports:
// BEFORE (Apollo Client 3.x)
import { useQuery, useMutation, useLazyQuery } from "@apollo/client";
import { ApolloProvider } from "@apollo/client";
import { useApolloClient } from "@apollo/client";
// AFTER (Apollo Client 4.x)
import { useQuery, useMutation, useLazyQuery } from "@apollo/client/react";
import { ApolloProvider } from "@apollo/client/react";
import { useApolloClient } from "@apollo/client/react";
Benefits:
- Better tree-shaking for non-React Apollo Client usage
- Clearer separation between core and React-specific functionality
- Reduced bundle size for React-only applications
Files Affected:
- All components using Apollo hooks (50+ files)
- Main app provider component
- GraphQL container components
useLazyQuery API Changes
The return value destructuring pattern for useLazyQuery changed in Apollo Client 4.x.
Example - Query Function Extraction:
// BEFORE (Apollo Client 3.x)
const [, { data, refetch, queryLoading }] = useLazyQuery(QUERY_RO_AND_OWNER_BY_JOB_PKS, {
variables: { jobids: [context.jobid] },
skip: !context?.jobid
});
// AFTER (Apollo Client 4.x)
const [loadRoAndOwnerByJobPks, { data, loading: queryLoading, error: queryError, refetch, called }] = useLazyQuery(
QUERY_RO_AND_OWNER_BY_JOB_PKS
);
// Call the query function explicitly when needed
useEffect(() => {
if (context?.jobid) {
loadRoAndOwnerByJobPks({ variables: { jobids: [context.jobid] } });
}
}, [context?.jobid, loadRoAndOwnerByJobPks]);
Key Changes:
- Query function must be destructured: Previously ignored with
,now must be named - Options moved to function call:
variablesand other options passed when calling the query function loadingrenamed: More consistent withuseQueryhook namingcalledproperty added: Track if the query has been executed at least once- No more
skipoption: Logic moved to conditional query execution
Benefits:
- More explicit control over when queries execute
- Better alignment with
useQueryAPI patterns - Clearer code showing query execution timing
Files Affected:
- card-payment-modal.component.jsx
- bill-form.container.jsx
- Multiple job and payment components
6. forwardRef Pattern Migration
React 19 simplifies ref handling by allowing ref to be passed as a regular prop, eliminating the need for forwardRef in most cases.
forwardRef Wrapper Removal
Example - Component Signature Change:
// BEFORE
import { forwardRef } from "react";
const BillLineSearchSelect = ({ options, disabled, allowRemoved, ...restProps }, ref) => {
const { t } = useTranslation();
return (
<Select
ref={ref}
options={generateOptions(options, allowRemoved, t)}
disabled={disabled}
{...restProps}
/>
);
};
export default forwardRef(BillLineSearchSelect);
// AFTER
const BillLineSearchSelect = ({ options, disabled, allowRemoved, ref, ...restProps }) => {
const { t } = useTranslation();
return (
<Select
ref={ref}
options={generateOptions(options, allowRemoved, t)}
disabled={disabled}
{...restProps}
/>
);
};
export default BillLineSearchSelect;
Key Changes:
refas regular prop: Moved from second parameter to first parameter as a regular prop- No
forwardRefimport needed: Removed from React imports - No
forwardRefwrapper: Export component directly - Same ref behavior: Works identically from parent component perspective
Benefits:
- Simpler component API (single parameter instead of two)
- Reduced boilerplate code
- Better TypeScript inference
- More intuitive for developers
Components Migrated:
- BillLineSearchSelect
- ContractStatusComponent
- CourtesyCarFuelComponent
- CourtesyCarReadinessComponent
- CourtesyCarStatusComponent
- EmployeeTeamSearchSelect
- FormInputNumberCalculator
- FormItemCurrency
- FormItemEmail
- 10+ additional form components
7. React.lazy Import Cleanup
React 19 makes React.lazy usage more seamless, and in some cases lazy imports were removed where they were no longer beneficial.
Example - Lazy Import Removal:
// BEFORE
import { lazy, Suspense, useEffect, useRef, useState } from "react";
const LazyComponent = lazy(() => import('./HeavyComponent'));
// AFTER
import { Suspense, useEffect, useRef, useState } from "react";
// Lazy loading handled differently or component loaded directly
Context:
- Some components had lazy imports removed where the loading behavior wasn't needed
Suspenseboundaries maintained for actual lazy-loaded components- React 19 improves Suspense integration
Files Affected:
- Multiple route components
- Dashboard components
- Heavy data visualization components
8. StrictMode Integration
React 19's StrictMode was explicitly added to help catch potential issues during development.
Addition:
import { StrictMode } from "react";
root.render(
<StrictMode>
<App />
</StrictMode>
);
Benefits:
- Detects unexpected side effects
- Warns about deprecated APIs
- Validates React 19 best practices
- Double-invokes effects in development to catch issues
Impact:
- Helps ensure components work correctly with React 19 compiler
- Catches potential issues with state management
- Comment added: "This handles React StrictMode double-mounting"
9. React 19 New Hooks (Added Documentation)
The upgrade includes documentation for React 19's new concurrent hooks:
useFormStatus
Track form submission state for better UX during async operations.
useOptimistic
Implement optimistic UI updates that rollback on failure.
useActionState
Manage server actions with pending states and error handling.
10. ESLint Configuration Updates
React Compiler Plugin Added
Addition to eslint.config.js:
plugins: {
"react-compiler": pluginReactCompiler
},
rules: {
"react-compiler/react-compiler": "error"
}
Purpose:
- Enforces React 19 compiler best practices
- Warns about patterns that prevent compiler optimizations
- Ensures code is compatible with automatic optimizations
11. Testing Library Updates
@testing-library/react
- Upgraded: ^16.3.1 → ^16.3.2
- Impact: React 19 compatibility maintained
- Tests continue to work with updated React APIs
12. Peer Dependencies Updates
Multiple packages updated their peer dependency requirements to support React 19:
Examples:
// BEFORE
"peerDependencies": {
"react": ">=16.9.0",
"react-dom": ">=16.9.0"
}
// AFTER
"peerDependencies": {
"react": ">=18.0.0",
"react-dom": ">=18.0.0"
}
Affected Packages:
- Multiple internal and external dependencies
- Ensures ecosystem compatibility with React 19
13. Ant Design 6 Changes
Icon Package Update
- @ant-design/icons upgraded from ^5.6.1 to ^6.1.0
- Icon imports remain compatible (no breaking changes in usage patterns)
Component API Compatibility
- Existing Ant Design component usage remains largely compatible
- Form.Item, Button, Modal, Table, and other components work with existing code
- No major API breaking changes required in application code
14. Validation & Quality Assurance
Based on the optimization summary included in the changes:
Deprecations Verified as Fixed ✓
- propTypes: None found (already removed or using TypeScript)
- defaultProps: None found (using default parameters instead)
- ReactDOM.render: Already using createRoot
- componentWillMount/Receive/Update: No legacy lifecycle methods found
- String refs: Migrated to ref objects and useRef hooks
Performance Improvements
- Cleaner, more readable code
- Reduced bundle size (removed unnecessary memoization wrappers)
- Better performance through compiler-optimized memoization
- Fewer function closures and re-creations
- Reduced memory overhead from eliminated deep cloning
Summary Statistics
Dependencies Updated
- Core: 3 major updates (React, Ant Design, Apollo Client)
- GraphQL: 2 packages (Apollo Client 3→4, apollo-link-logger 2→3)
- Ecosystem: 10+ related libraries (router, i18next, grid layout, etc.)
- Build Tools: 3 plugins/tools (Vite plugins, vitest)
- Monitoring: 6 packages (Sentry, LogRocket, PostHog, Amplitude)
- Infrastructure: Node.js 22 → 24
Code Patterns Modernized
- useMemo removals: 15+ instances across multiple files
- useCallback removals: 10+ instances
- memo() wrapper removals: 5+ components
- Deep clone eliminations: Multiple state management simplifications
- Import cleanups: Dozens of simplified import statements
- Apollo import migrations: 50+ files updated to
/reactimports - forwardRef removals: 15+ components migrated to direct ref props
- useLazyQuery updates: Multiple query patterns updated for Apollo 4.x API
- lazy import cleanups: Several unnecessary lazy imports removed
- StrictMode integration: Added to development builds
Files Impacted
- Production board kanban components: Compiler optimization removals
- Trello-board controllers and components: Memoization removals
- Job management components: State management simplifications
- All GraphQL components: Apollo Client 4.x import migrations (50+ files)
- Form components: forwardRef pattern migrations (15+ components)
- Payment components: useLazyQuery API updates
- Various utility components: Import cleanups
- Build configuration files: ESLint React compiler plugin
- Docker infrastructure: Node.js 22→24 upgrade
- App root: StrictMode integration
- Package manifests: 30+ dependency upgrades
Recommendations for Future Development
- Avoid Manual Memoization: Let React 19 compiler handle optimization automatically
- Use ESLint React Compiler Plugin: Catch patterns that prevent optimizations
- Maintain Referential Stability: Use constant empty arrays/objects instead of creating new ones
- Leverage New React 19 Hooks: Use
useOptimistic,useFormStatus, anduseActionStatefor better UX - Monitor Compiler Warnings: Address any compiler optimization warnings during development
- Apollo Client 4.x Imports: Always import React hooks from
@apollo/client/react - Ref as Props: Use
refas a regular prop instead offorwardRefwrapper - useLazyQuery Pattern: Extract query function and call explicitly rather than using
skipoption - StrictMode Aware: Ensure components handle double-mounting in development properly
- Keep Dependencies Updated: Monitor for peer dependency compatibility as ecosystem evolves
Conclusion
This comprehensive upgrade successfully modernizes the codebase across multiple dimensions:
Major Achievements
- React 19 Migration: Leveraged new compiler optimizations by removing manual memoization
- Apollo Client 4.x: Updated all GraphQL operations to new import patterns and APIs
- Ant Design 6: Maintained UI consistency while gaining access to latest features
- forwardRef Elimination: Simplified 15+ components by using refs as regular props
- Dependency Modernization: Updated 30+ packages including monitoring, build tools, and ecosystem libraries
- Infrastructure Upgrade: Node.js 24.x support for latest runtime features
Code Quality Improvements
- Cleaner code: Removed unnecessary wrappers and boilerplate
- Better performance: Compiler-optimized rendering without manual hints
- Reduced bundle size: Removed lodash cloning, unnecessary lazy imports, and redundant memoization
- Improved maintainability: Simpler patterns that are easier to understand and modify
- Enhanced DX: ESLint integration catches optimization blockers during development
Migration Completeness
✅ All React 18→19 deprecations addressed
✅ All Apollo Client 3→4 breaking changes handled
✅ All Ant Design 5→6 updates applied
✅ All monitoring libraries updated to latest versions
✅ StrictMode integration for development safety
✅ Comprehensive testing library compatibility maintained
No breaking changes to application functionality - The upgrade maintains backward compatibility in behavior while providing forward-looking improvements in implementation.