Update React dependencies to v19#32473
Conversation
- Bump react and react-dom from 18.3.1 to 19.1.0
- Bump @types/react from 18.3.12 to 19.1.6
- Bump @types/react-dom from 18.3.1 to 19.1.6
- Add findDOMNode polyfill (react-dom-compat.ts) for reactstrap/react-transition-group compatibility since findDOMNode was removed in React 19
- Import polyfill in index.tsx and setup-tests.ts before any library usage
- Replace bare JSX.Element with React.JSX.Element (global JSX namespace removed in @types/react 19)
- Add triple-slash reference directive in typings.d.ts for React types
- Add non-null assertion on getElementById('root') for stricter types
- Add npm overrides for react-redux-loading-bar and react-jhipster peer deps
- Update test snapshots
Closes jhipster#28130
|
@teredasites Please update reacstrap version |
There was a problem hiding this comment.
Pull request overview
Updates the React generator templates to React 19 (runtime + type packages) and applies template-level fixes for React 19 breaking changes (notably removal of findDOMNode and the global JSX namespace).
Changes:
- Bumped
react,react-dom, and related@types/*packages to React 19. - Added a
react-domcompatibility shim to restorefindDOMNodefor legacy dependencies. - Updated template type annotations from
JSX.ElementtoReact.JSX.Elementand added an ambient React types reference.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| generators/react/templates/src/main/webapp/app/typings.d.ts.ejs | Adds React types reference and updates microfrontend typings to React.JSX.Element. |
| generators/react/templates/src/main/webapp/app/shared/error/error-boundary-routes.spec.tsx.ejs | Updates test component return types to React.JSX.Element. |
| generators/react/templates/src/main/webapp/app/shared/auth/private-route.spec.tsx.ejs | Updates wrapper parameter type to React.JSX.Element. |
| generators/react/templates/src/main/webapp/app/setup-tests.ts.ejs | Imports the findDOMNode compatibility shim in test setup. |
| generators/react/templates/src/main/webapp/app/index.tsx.ejs | Imports the shim before other imports and adds a non-null assertion for the root element. |
| generators/react/templates/src/main/webapp/app/config/react-dom-compat.ts.ejs | New shim that polyfills ReactDOM.findDOMNode. |
| generators/react/templates/package.json.ejs | Adds npm overrides to work around peer dependency ranges not yet updated to React 19. |
| generators/react/resources/package.json | Updates React and type dependency versions to React 19. |
| generators/react/files-react.ts | Registers the new shim template file for generation. |
| generators/react/snapshots/generator.spec.ts.snap | Snapshot updates to include the newly generated shim file. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| let node = fiber; | ||
| while (node) { | ||
| if (node.stateNode instanceof Element || node.stateNode instanceof Text) { | ||
| return node.stateNode; | ||
| } | ||
| node = node.child; |
There was a problem hiding this comment.
The fiber traversal only follows child pointers and never explores sibling (or walks back up via return), so it can incorrectly return null even when a host DOM/Text node exists elsewhere in the subtree. Consider switching to a small DFS traversal (child → sibling → return) so the shim can find the first stateNode that is an Element/Text in more real-world component trees.
| let node = fiber; | |
| while (node) { | |
| if (node.stateNode instanceof Element || node.stateNode instanceof Text) { | |
| return node.stateNode; | |
| } | |
| node = node.child; | |
| const stack: any[] = [fiber]; | |
| while (stack.length > 0) { | |
| const node = stack.pop(); | |
| if (!node) { | |
| continue; | |
| } | |
| if (node.stateNode instanceof Element || node.stateNode instanceof Text) { | |
| return node.stateNode; | |
| } | |
| if (node.sibling) { | |
| stack.push(node.sibling); | |
| } | |
| if (node.child) { | |
| stack.push(node.child); | |
| } |
| if ((componentOrElement as Element).nodeType != null) { | ||
| return componentOrElement as Element; |
There was a problem hiding this comment.
This branch treats any nodeType as an Element, but callers may pass a Text node (and your function signature includes Text). Returning componentOrElement as Element is type-incorrect and can mislead downstream code. Use a Node-compatible type (or Element | Text) for the cast/return in this branch to match the runtime behavior.
| if ((componentOrElement as Element).nodeType != null) { | |
| return componentOrElement as Element; | |
| if ((componentOrElement as Node).nodeType != null) { | |
| return componentOrElement as Element | Text; |
| import ErrorBoundaryRoutes from './error-boundary-routes'; | ||
|
|
||
| const ErrorComp = (): JSX.Element => { | ||
| const ErrorComp = (): React.JSX.Element => { |
There was a problem hiding this comment.
These templates now reference the React namespace for types but do not explicitly import React types. In TypeScript setups that restrict compilerOptions.types, this can fail with Cannot find namespace 'React'. A more robust pattern is to add an explicit type-only import (e.g. import type * as React from 'react';) or import JSX from react and use JSX.Element from that import.
| }; | ||
|
|
||
| const NoErrorComp = (): JSX.Element => { | ||
| const NoErrorComp = (): React.JSX.Element => { |
There was a problem hiding this comment.
These templates now reference the React namespace for types but do not explicitly import React types. In TypeScript setups that restrict compilerOptions.types, this can fail with Cannot find namespace 'React'. A more robust pattern is to add an explicit type-only import (e.g. import type * as React from 'react';) or import JSX from react and use JSX.Element from that import.
| <%_ } _%> | ||
|
|
||
| const wrapper = (Elem: JSX.Element, authentication) => { | ||
| const wrapper = (Elem: React.JSX.Element, authentication) => { |
There was a problem hiding this comment.
Similar to the other spec template, this introduces a dependency on the global React namespace for typing without an explicit type-only import. To avoid Cannot find namespace 'React' in projects that restrict compilerOptions.types, prefer an explicit type-only import (or import JSX from react and use JSX.Element).
|
Fixed in #32495 by moving to react-bootstrap. |
Summary
Update React and related type packages to version 19, addressing all breaking changes in generated application code.
Closes #28130
Changes
Dependency Updates
react: 18.3.1 -> 19.1.0react-dom: 18.3.1 -> 19.1.0@types/react: 18.3.12 -> 19.1.6@types/react-dom: 18.3.1 -> 19.1.6Breaking Change Fixes
findDOMNoderemoved in React 19react-dom-compat.tspolyfill that restores a basicfindDOMNodeimplementation on thereact-dommodule. This is required becausereactstrapdepends onreact-transition-groupwhich callsReactDOM.findDOMNodeinternally.index.tsx(before any library code) and insetup-tests.ts(for test compatibility).Global
JSXnamespace removed in@types/react19JSX.Elementreferences withReact.JSX.Elementin:typings.d.ts.ejs(microfrontend module declarations)error-boundary-routes.spec.tsx.ejsprivate-route.spec.tsx.ejs/// <reference types="react" />triple-slash directive intypings.d.tsto ensure React types are available forReact.JSX.Elementin ambient declarations.Stricter null types
!) ondocument.getElementById('root')inindex.tsxsincecreateRoot()in React 19 is stricter about null arguments.Peer dependency conflicts
overridessection in generatedpackage.jsonforreact-redux-loading-barandreact-jhipsterwhich haven't updated their peer dependency ranges to include React 19 yet.Files Changed
generators/react/resources/package.json- Version bumpsgenerators/react/files-react.ts- Register new polyfill templategenerators/react/templates/src/main/webapp/app/config/react-dom-compat.ts.ejs- New findDOMNode polyfillgenerators/react/templates/src/main/webapp/app/index.tsx.ejs- Import polyfill, null assertion fixgenerators/react/templates/src/main/webapp/app/setup-tests.ts.ejs- Import polyfill for testsgenerators/react/templates/src/main/webapp/app/typings.d.ts.ejs- React reference directive, JSX.Element fixgenerators/react/templates/package.json.ejs- npm overrides for peer depsgenerators/react/templates/src/main/webapp/app/shared/error/error-boundary-routes.spec.tsx.ejs- JSX.Element fixgenerators/react/templates/src/main/webapp/app/shared/auth/private-route.spec.tsx.ejs- JSX.Element fixgenerators/react/__snapshots__/generator.spec.ts.snap- Updated snapshotsTest plan
esmocha generators/react/generator.spec.ts)react-dom-compat.tsfile