Skip to content

chore(settings): Update to React 19 - #20963

Merged
xlisachan merged 1 commit into
mainfrom
PAY-3887
Sep 1, 2026
Merged

chore(settings): Update to React 19#20963
xlisachan merged 1 commit into
mainfrom
PAY-3887

Conversation

@xlisachan

@xlisachan xlisachan commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

This pull request

  • Upgrades React and react-dom to 19 (pinned to 19.0.8), with @types/react 19 and @testing-library/react 16
  • Switches [fxa-settings](https://mozilla-hub.atlassian.net/browse/FXA-settings) to createRoot; ReactDOM.render is gone in React 19
  • Moves render-phase navigate() calls into effects across 13 containers — a concurrent root commits asynchronously, so navigating during render races the commit
  • Replaces the hand-rolled Symbol.for('react.element') in the SVG Jest transform with createElement, and consolidates the duplicated transform into [fxa-react](https://mozilla-hub.atlassian.net/browse/FXA-react)
  • Migrates useFormState to useActionState in CouponForm, dispatching the auto-apply through startTransition
  • Drops @material-ui/core (peers on React ^16/^17) and rebuilds the avatar zoom control as a native range input
  • Removes @testing-library/react-hooks, which has no React 19 support, in favour of RTL's renderHook
  • Fixes functional-test page objects that assumed the route committed with the URL

Other information

  • React is pinned to 19.0.8, not 19.2.x. 19.2.8 reproducibly failed six passkey and 2FA
    functional tests that pass on 19.0.8, on two independent branches. The cause is not diagnosed;
    bumping to 19.2.x should be its own change. (FXA-14313)
  • StrictMode is disabled in [fxa-settings](https://mozilla-hub.atlassian.net/browse/FXA-settings)/src/index.tsx. PagePasskeyAdd starts its WebAuthn
    ceremony in a mount effect and the double-invoke aborts it. Fixing that effect's cleanup and
    restoring StrictMode is follow-up work. (FXA-14313)

Closes PAY-3887

Issue that this pull request solves

Closes: PAY-3887

Checklist

Put an x in the boxes that apply

  • My commit is GPG signed.
  • If applicable, I have modified or added tests which pass locally.

This comment was marked as resolved.

@xlisachan
xlisachan force-pushed the PAY-3633 branch 5 times, most recently from f719832 to fa7a3da Compare August 6, 2026 14:09
@xlisachan
xlisachan force-pushed the PAY-3887 branch 3 times, most recently from 3ea8a3a to 46d78ad Compare August 6, 2026 18:43
@xlisachan
xlisachan marked this pull request as ready for review August 6, 2026 19:44
@xlisachan
xlisachan force-pushed the PAY-3887 branch 14 times, most recently from fc2597a to bcaae6d Compare August 26, 2026 18:44
@StaberindeZA
StaberindeZA requested a balanced review from Copilot August 26, 2026 19:17

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 67 out of 69 changed files in this pull request and generated 9 comments.

Suppressed comments (1)

packages/fxa-settings/src/pages/Signin/SigninTotpCode/container.tsx:150

  • This effect can navigate to / while either OAuth error branch below is being rendered. Previously those error returns occurred before the redirect guard, so this changes the behavior from displaying the error to silently leaving the page. Preserve both error guards in the effect.

Comment thread packages/fxa-settings/src/pages/Signin/container.tsx Outdated
Comment thread packages/fxa-settings/src/pages/Signin/SigninUnblock/container.tsx Outdated
Comment thread packages/fxa-settings/src/pages/Signin/SigninTotpCode/container.tsx Outdated
Comment thread packages/fxa-settings/src/pages/PostVerify/SetPassword/container.tsx Outdated
Comment thread packages/fxa-settings/src/pages/ResetPassword/CompleteResetPassword/container.tsx Outdated
Comment thread package.json
Comment on lines +68 to +71
await expect(async () => {
await this.codeInput.fill(code);
await expect(this.codeInput).toHaveValue(code);
}).toPass({ timeout: 15000 });
Comment thread libs/payments/ui/src/lib/client/components/CouponForm/index.tsx
@xlisachan
xlisachan marked this pull request as ready for review August 27, 2026 16:52
@xlisachan
xlisachan requested a review from a team as a code owner August 27, 2026 16:52
return;
}

// INSUFFICIENT_AAL is handled by the auth client's global error

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: I know this came up in a previous review, but looking at this again these INSUFFICIENT_AAL changes seem unrelated to the upgrade and I wonder if we should omit (incl. new tests, l10n string)?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like we can, but there are still minor updates to the file since ReactDOM.render was removed in 19. LMK your thoughts!

Comment thread package.json
"prettier": "^3.5.3",
"react": "18.3.1",
"react-dom": "18.3.1",
"react": "19.0.8",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The git commit message has a buried note about pining to 19.08 vs the more recent React 19 version - if this is necessary even with the Strict mode disabling, it should be noted in the PR description and with a code comment. The commit message also includes unspecified Jira ticket numbers - that should be updated.

For ref, the ticket to re-enable strict mode (and possibly bump React to 19.2+, though not noted in current description) is FXA-14313

Comment thread packages/fxa-settings/src/index.tsx Outdated
</React.StrictMode>,
document.getElementById('root')
const root = createRoot(document.getElementById('root') as HTMLElement);
// StrictMode disabled: PagePasskeyAdd auto-starts the ceremony in a

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: Simplify comment to
TODO: re-enable strict mode in FXA-14313

if (!uid || !sessionToken) {
navigateWithQuery('/signin', { replace: true });
return;
// Navigate from an effect; a render-phase navigation races the commit.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: I feel like we could clean up all the "navigate from an effect" comments. These explain the changes in the PR but won't be helpful in the future.

return <AppLayout cmsInfo={integration.getCmsInfo()} loading />;
}

// we only care about "verified" here, not "exists"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ask: I feel like some of our helpful comments like this one were stripped out... Can we re-add, maybe have Claude do a pass of the diff and re-add the lost context like this?

]
);

// Users must be already authenticated on this page.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another example of lost context...

@@ -0,0 +1,4 @@
# Shown inside the MFA dialog when the account needs a higher authentication

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we spell out MFA?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have removed this update, so it is no longer needed :)

@xlisachan
xlisachan force-pushed the PAY-3887 branch 2 times, most recently from a039ac2 to 1b091d7 Compare August 31, 2026 20:43
@xlisachan
xlisachan requested a review from vpomerleau August 31, 2026 21:10

@vpomerleau vpomerleau left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the updates!

This pull request:

- Upgrades React and react-dom to 19 (pinned to `19.0.8`), with `@types/react` 19 and `@testing-library/react` 16
- Switches `fxa-settings` to `createRoot`; `ReactDOM.render` is gone in React 19
- Moves render-phase `navigate()` calls into effects across 13 containers — a concurrent root commits asynchronously, so navigating during render races the commit
- Replaces the hand-rolled `Symbol.for('react.element')` in the SVG Jest transform with `createElement`, and consolidates the duplicated transform into `fxa-react`
- Migrates `useFormState` to `useActionState` in `CouponForm`, dispatching the auto-apply through `startTransition`
- Drops `@material-ui/core` (peers on React ^16/^17) and rebuilds the avatar zoom control as a native range input
- Removes `@testing-library/react-hooks`, which has no React 19 support, in favour of RTL's `renderHook`
- Fixes functional-test page objects that assumed the route committed with the URL

Other information
- **React is pinned to 19.0.8, not 19.2.x.** 19.2.8 reproducibly failed six passkey and 2FA
  functional tests that pass on 19.0.8, on two independent branches. The cause is not diagnosed;
  bumping to 19.2.x should be its own change. (FXA-14313)
- **`StrictMode` is disabled** in `fxa-settings/src/index.tsx`. `PagePasskeyAdd` starts its WebAuthn
  ceremony in a mount effect and the double-invoke aborts it. Fixing that effect's cleanup and
  restoring StrictMode is follow-up work. (FXA-14313)

Closes PAY-3887
@xlisachan
xlisachan merged commit 376a6e1 into main Sep 1, 2026
21 checks passed
@xlisachan
xlisachan deleted the PAY-3887 branch September 1, 2026 13:51
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.

4 participants