React 18 upgrade POC
/hold
can we check the conflicts with base branch
can we check the conflicts with base branch
Hey, unfortunately this PR is still very experimental and we're unlikely to make this upgrade by the end of our internal deadlines for this release.
If your team is blocked by this upgrade, consider filing a support ticket or adding a comment to the corresponding Jira issue.
Thanks for your interest!
/uncc christoph-jerolimov Lucifergene
Walkthrough
This pull request performs a comprehensive upgrade to React 18, react-redux 8, and i18next, coupled with widespread refactoring of Redux hooks, React lifecycle methods, translation interpolation patterns, and performance optimizations across the console application and plugin ecosystem.
Changes
| Cohort / File(s) | Summary |
|---|---|
Dependency Updates dynamic-demo-plugin/package.json, frontend/package.json, frontend/packages/console-plugin-shared/package.json |
React upgraded from 17.x to 18.2.0; react-dom, react-redux, i18next, and react-i18next updated to newer versions. @types/react and @types/react-dom updated to 18.x. Console-plugin-shared peer dependency adjusted. |
Redux Hook Replacements frontend/packages/console-app/src/actions/hooks/useBindingActions.ts, useGroupActions.ts, frontend/packages/console-app/src/actions/providers/user-provider.ts, frontend/packages/console-shared/src/.../{prometheus-hook.ts,useDashboardResources.ts}, frontend/packages/operator-lifecycle-manager/src/components/operand/index.tsx, frontend/public/components/masthead/masthead-toolbar.tsx, frontend/public/components/useImpersonateRefreshFeatures.ts |
Replaced react-redux useDispatch/useSelector with custom useConsoleDispatch/useConsoleSelector hooks throughout codebase for centralized state management. |
Console Redux Hook Exports frontend/packages/console-app/src/hooks/redux.ts |
New module exporting typed Redux hooks: useConsoleDispatch, useConsoleSelector, useConsoleStore with proper ThunkDispatch and RootState typing. |
Redux Types & Dynamic Plugin SDK Updates frontend/packages/console-dynamic-plugin-sdk/src/app/redux-types.ts, frontend/packages/console-dynamic-plugin-sdk/src/utils/k8s/hooks/{useK8sWatchResource.ts,useK8sWatchResources.ts} |
Added SDKDispatch type export; updated dispatch and selector usage to use typed SDKDispatch and SDKStoreState throughout k8s watch hooks. |
React 18 Lifecycle Migration frontend/public/components/graphs/status.jsx, frontend/public/components/utils/{firehose.jsx,storage-class-dropdown.tsx} |
Replaced UNSAFE_componentWillMount/UNSAFE_componentWillReceiveProps with componentDidMount/componentDidUpdate for React 18 compliance. |
React 18 Root API Migration frontend/public/components/app.tsx, frontend/public/components/factory/modal.tsx |
Migrated from ReactDOM.render to React 18 createRoot API with root.render pattern for application bootstrapping and modal rendering. |
Feature Flag Management Refactoring frontend/public/actions/features.ts, frontend/packages/console-app/src/components/flags/{FeatureFlagExtensionHookResolver.tsx,FeatureFlagExtensionLoader.tsx} |
Unexported featureFlagController, added deferred dispatch with queueMicrotask; converted components to named exports; introduced useFeatureFlagController hook for flag updates. |
Reducer Optimization & Memoization frontend/packages/console-dynamic-plugin-sdk/src/app/k8s/reducers/k8s.ts, frontend/public/reducers/{features.ts,observe.ts}, frontend/packages/console-plugin-sdk/src/api/pluginSubscriptionService.ts |
Batched mutations with withMutations to reduce ImmutableMap allocations; added caching for feature flags and model objects; conditional updates to prevent unnecessary re-renders. |
Selector Memoization frontend/public/reducers/connectToFlags.ts, frontend/packages/console-dynamic-plugin-sdk/src/utils/k8s/hooks/useK8sModels.ts |
Introduced memoized selectors via createSelector and useDeepCompareMemoize to prevent unnecessary object recreation and re-renders. |
Topology Data Memoization frontend/packages/topology/src/data-transforms/{DataModelExtension.tsx,DataModelProvider.tsx,TopologyDataRetriever.tsx} |
Applied deep-compare memoization to model factories, resolved factories, and watched resources to stabilize references and prevent re-renders. |
Component Type Signature Updates frontend/packages/topology/src/components/{list-view/ListElementWrapper.tsx,graph-view/components/edges/BaseEdge.tsx,side-bar/providers/useDetailsResourceLink.tsx} |
Added optional children prop to ListElementWrapperProps; refined observer HOC typing; updated return types to React.ReactNode. |
DropDown & Resource Components Refactoring frontend/packages/console-shared/src/components/dropdown/ResourceDropdown.tsx |
Replaced UNSAFE_componentWillReceiveProps with componentDidUpdate; added loading/error state guards; enhanced change detection and onLoad invocation. |
API Explorer Conversion frontend/public/components/api-explorer.tsx |
Converted APIResourcesList from HOC (connect + withRouter) to functional component using useLocation and useConsoleSelector hooks. |
| i18n Translation Interpolation Updates Multiple files including console-app/src/components/{modals/restore-pvc/restore-pvc-modal.tsx,nav/useConfirmNavUnpinModal.tsx,nodes/NodesPage.tsx,pdb/modals/DeletePDBModal.tsx,volume-snapshot/...tsx}, frontend/packages/dev-console/src/components/{import/toast/WebhookToastContent.tsx,pipeline-section/pipeline/PacInfoPanel.tsx}, frontend/packages/helm-plugin/src/components/{details-page/history/...,forms/{HelmChartVersionDropdown.tsx,rollback/...}}, frontend/packages/knative-plugin/src/components/{sink-pubsub/SinkPubsubModal.tsx,sink-source/SinkSourceModal.tsx}, frontend/packages/operator-lifecycle-manager/src/components/{clusterserviceversion.tsx,descriptors/common.tsx,index.tsx,modals/{delete-catalog-source-modal.tsx,uninstall-operator-modal.tsx},operator-hub/operator-hub-subscribe.tsx}, frontend/packages/topology/src/components/{modals/{EditApplicationModal.tsx,MoveConnectionModal.tsx},export-app/ExportApplicationModal.tsx,utils/moveNodeToGroup.tsx}, frontend/public/components/modals/{delete-modal.tsx,delete-namespace-modal.tsx,delete-pvc-modal.tsx,expand-pvc-modal.tsx,remove-idp-modal.tsx,remove-volume-modal.tsx}, frontend/public/components/{container.tsx,about-modal.tsx,error.tsx} |
Changed translation interpolation from inline object syntax to i18n values props with literal placeholder strings in rendered output (e.g., {{ name }} replaced with values={{ name }} and literal '{{ name }}' rendering). |
Localization String Formatting frontend/packages/console-app/locales/en/console-app.json, frontend/packages/dev-console/locales/en/devconsole.json, frontend/packages/helm-plugin/locales/en/helm-plugin.json, frontend/packages/knative-plugin/locales/en/knative-plugin.json, frontend/packages/operator-lifecycle-manager/locales/en/olm.json, frontend/packages/topology/locales/en/topology.json |
Updated placeholder spacing inside Mustache expressions (e.g., {{name}} → {{ name }}); adjusted HTML tag indices in interpolations. |
Type Signature & Import Updates frontend/packages/console-plugin-sdk/src/utils/{useTranslationExt.ts,extension-i18n.spec.ts}, frontend/packages/console-shared/src/utils/yup-validations.ts, frontend/packages/topology/src/__tests__/TopologyShortcuts.spec.tsx, frontend/packages/vsphere-plugin/src/components/{persist.ts,utils.ts}, frontend/packages/metal3-plugin/src/validations/validations.tsx |
Updated TFunction import source from react-i18next to i18next; loosened type constraints; added type casts where needed. |
Extension Type Broadening frontend/packages/console-dynamic-plugin-sdk/docs/console-extensions.md, frontend/packages/console-dynamic-plugin-sdk/src/extensions/{console-types.ts,topology-details.ts} |
Broadened return types from React.Component to React.ReactNode for DetailsResourceLink, DetailsTabSection; added optional children prop to CreateWithPermissionsProps. |
Component Type Conversions frontend/public/components/custom-resource-definition.tsx, frontend/public/components/{factory/list-page.tsx,factory/table.tsx} |
Converted React.FC to React.FCC for several components; added optional children props to FireManProps and TableRowProps. |
Fragment Wrapping Returns frontend/public/components/{cron-job.tsx,modals/column-management-modal.tsx}, dynamic-demo-plugin/src/components/CustomOverviewDetailItem.tsx, frontend/packages/console-app/src/components/nodes/NodesPage.tsx, frontend/packages/operator-lifecycle-manager/src/components/clusterserviceversion.tsx, frontend/public/components/{about-modal.tsx,error.tsx} |
Wrapped translation string returns in React fragments to convert return type from string to React.ReactNode. |
Test Helper Type Updates frontend/packages/dev-console/src/components/buildconfig/sections/__tests__/{EnvironmentVariablesSection.spec.tsx,NameSection.spec.tsx,PolicySection.spec.tsx,SecretsSection.spec.tsx,SourceSection.spec.tsx,TriggersSection.spec.tsx}, frontend/packages/dev-console/src/components/catalog/providers/__tests__/useConsoleSamples.spec.ts, frontend/packages/dev-console/src/components/import/__tests__/import-submit-utils.spec.ts |
Introduced WrapperProps interfaces extending FormikConfig with optional children; updated TFunction typing in test fixtures. |
Miscellaneous Component & Logic Updates frontend/packages/metal3-plugin/src/components/baremetal-hosts/BareMetalHostStatus.tsx, frontend/public/components/modals/configure-count-modal.tsx, frontend/packages/operator-lifecycle-manager/src/components/descriptors/spec/index.tsx, frontend/packages/operator-lifecycle-manager/src/status/csv-status.ts, frontend/public/components/modals/delete-resource-modal.tsx, frontend/packages/dev-console/src/components/projects/details/ProjectDetailsPage.tsx, frontend/packages/dev-console/src/components/user-preferences/SecureRouteFields.tsx, frontend/packages/knative-plugin/src/topology/components/edges/EventingPubSubLink.tsx, frontend/packages/vsphere-plugin/src/components/{ClusterOverview/VSphereStatus.tsx,getVSphereHealth.ts}, frontend/packages/console-dynamic-plugin-sdk/src/utils/k8s/hooks/__tests__/useK8sModels.spec.tsx, frontend/packages/console-dynamic-plugin-sdk/docs/console-extensions.md |
Conditionally render PopoverStatus wrappers; add explicit type casts; swap function parameter order; modify component prop presence; adjust test expectations for memoization. |
Documentation frontend/packages/console-dynamic-plugin-sdk/README.md |
Added Console 4.22.X upgrade notes for react-redux v7→v8; provided PatternFly 5+ dynamic module guidance. |
Estimated code review effort
🎯 5 (Critical) | ⏱️ ~120+ minutes
Areas requiring extra attention:
- i18n Translation Changes: Widespread replacement of inline interpolation with literal placeholder strings carries high risk of rendering actual placeholder text instead of dynamic values. Verify that translations are correctly interpolating values and not displaying
{{ name }}literally across all modified files. - Redux State Selection & Dispatch: Verify that new useConsoleDispatch/useConsoleSelector hooks correctly handle all state access patterns and that type signatures match expected RootState shapes throughout the codebase.
- React 18 Lifecycle Migrations: Confirm componentDidMount/componentDidUpdate properly initialize state and handle prop changes as intended; check for missed edge cases in componentDidUpdate guards and dependency arrays.
- Reducer Batch Mutations & Caching: Review k8s.ts reducer and feature reducer for correctness of withMutations batching logic and guard conditions to ensure no state mutations are skipped unintentionally.
- Memoization & Reference Stability: Inspect deep-compare memoization usage in topology components and selectors to ensure memoization keys are correct and dependencies are properly declared.
- React 18 createRoot Migration: Verify root lifecycle, cleanup on unmount, and error boundary behavior in app.tsx and modal.tsx are correct under React 18 semantics.
- Type Signature Broadening: Confirm React.ReactNode return type changes (from React.Component | undefined) do not introduce rendering issues and properly handle null/undefined cases.
- Translation Placeholder Rendering: Cross-check multiple modal and message files to ensure values props and literal placeholder strings align with i18n configuration and don't result in broken interpolations.
✨ Finishing touches
- [ ] 📝 Generate docstrings
🧪 Generate unit tests (beta)
- [ ] Create PR with unit tests
- [ ] Post copyable unit tests in a comment
Comment @coderabbitai help to get the list of available commands and usage tips.
[APPROVALNOTIFIER] This PR is NOT APPROVED
This pull-request has been approved by: logonoff Once this PR has been reviewed and has the lgtm label, please ask for approval from jhadvig. For more information see the Code Review Process.
The full list of commands accepted by this bot can be found here.
Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment
@logonoff: The following tests failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:
| Test name | Commit | Details | Required | Rerun command |
|---|---|---|---|---|
| ci/prow/e2e-gcp-console | 86408e7bc5487b4b1fef20e47b8dae9aa8358d4e | link | true | /test e2e-gcp-console |
| ci/prow/images | 86408e7bc5487b4b1fef20e47b8dae9aa8358d4e | link | true | /test images |
| ci/prow/okd-scos-images | 86408e7bc5487b4b1fef20e47b8dae9aa8358d4e | link | true | /test okd-scos-images |
| ci/prow/analyze | 86408e7bc5487b4b1fef20e47b8dae9aa8358d4e | link | true | /test analyze |
| ci/prow/frontend | 86408e7bc5487b4b1fef20e47b8dae9aa8358d4e | link | true | /test frontend |
Full PR test history. Your PR dashboard.
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.