From 34043f99d989800c14f340b71f12d9d245d29a0c Mon Sep 17 00:00:00 2001
From: AtofStryker <bglesias@gmail.com>
Date: Fri, 8 Nov 2024 12:33:45 -0500
Subject: [PATCH 1/2] breaking: remove support for react 16 and 17 for
 component testing and move cypress/react18 upstream into cypress/react [run
 ci]

---
 .circleci/cache-version.txt                   |   2 +-
 .circleci/workflows.yml                       |  10 +-
 CHANGELOG.md                                  |   1 -
 CONTRIBUTING.md                               |   1 -
 cli/.eslintignore                             |   1 -
 cli/CHANGELOG.md                              |   6 +-
 cli/package.json                              |   7 -
 cli/scripts/post-build.js                     |   1 -
 .../app-action-example/counter.cy.jsx         |   8 +-
 .../advanced/app-action-example/counter.jsx   |  44 +-
 .../component/advanced/context/App.jsx        |  20 +-
 .../advanced/mocking-axios/1-users.jsx        |  49 +-
 ...{3-users-api.cy.jsx => 2-users-api.cy.jsx} |   4 +-
 .../advanced/mocking-axios/2-users-api.jsx    |  29 ++
 .../mocking-axios/2-users-named.cy.jsx        |  36 --
 .../advanced/mocking-axios/2-users-named.jsx  |  33 --
 .../advanced/mocking-axios/3-users-api.jsx    |  34 --
 .../advanced/renderless/mouse-movement.jsx    |  66 ++-
 .../advanced/renderless/mouse.cy.jsx          |  30 +-
 .../advanced/set-timeout-example/App.jsx      |  46 +-
 .../set-timeout-example/LoadingIndicator.jsx  |  43 +-
 .../advanced/timers/card-without-effect.jsx   |   1 +
 .../advanced/tutorial/shopping-list.jsx       |  24 +-
 .../component/advanced/tutorial/square.cy.jsx |  26 +-
 .../advanced/tutorial/tic-tac-toe.cy.jsx      |   2 +-
 .../advanced/tutorial/tic-tac-toe.jsx         | 186 ++++----
 .../cypress/component/basic/css/Button.jsx    |  30 +-
 .../cypress/component/basic/enzyme/README.md  |  98 ----
 .../component/basic/enzyme/context.cy.jsx     |  53 ---
 .../component/basic/enzyme/props.cy.jsx       |  82 ----
 .../basic/enzyme/simple-component.jsx         |  24 -
 .../component/basic/enzyme/simple-context.jsx |   4 -
 .../component/basic/enzyme/state.cy.jsx       |  60 ---
 .../component/basic/network/1-users.jsx       |  48 +-
 .../component/basic/network/2-users-fetch.jsx |  50 +-
 .../basic/react-tutorial/game.cy.jsx          |  14 +-
 .../component/basic/react-tutorial/game.jsx   | 178 +++----
 .../basic/react-tutorial/shopping-list.jsx    |  24 +-
 .../basic/react-tutorial/square1.jsx          |  14 +-
 .../basic/react-tutorial/square2.jsx          |  21 +-
 .../basic/react-tutorial/square3.jsx          |  23 +-
 .../basic/react-tutorial/square4.jsx          |   6 +-
 .../component/basic/rerender/effects.cy.jsx   |   7 +-
 .../component/basic/unmount/comp.cy.jsx       |   3 +-
 .../cypress/component/basic/unmount/comp.jsx  |  18 +-
 .../component/basic/unmount/unmount.cy.jsx    |  45 --
 .../basic/use-render/my-component.jsx         |   7 +-
 npm/react/package.json                        |  28 +-
 npm/react/src/mount.ts                        |  56 +--
 npm/react/src/types.ts                        |   6 +-
 npm/react18/.eslintignore                     |   5 -
 npm/react18/.releaserc.js                     |   3 -
 npm/react18/CHANGELOG.md                      |  47 --
 npm/react18/README.md                         |   7 -
 npm/react18/package.json                      |  71 ---
 npm/react18/rollup.config.mjs                 |   3 -
 npm/react18/src/index.ts                      |  92 ----
 npm/react18/tsconfig.json                     |  22 -
 .../cypress/e2e/vite-dev-server.cy.ts         |   2 +-
 npm/vite-plugin-cypress-esm/README.md         |  12 +-
 npm/vite-plugin-cypress-esm/cypress.config.ts |   7 +-
 npm/vite-plugin-cypress-esm/package.json      |  10 +-
 npm/vue/package.json                          |   3 -
 npm/webpack-preprocessor/package.json         |   3 -
 .../cypress/e2e/config-warning.cy.ts          |   4 +-
 .../reporter/cypress/support/component.ts     |   2 +-
 packages/scaffold-config/src/dependencies.ts  |   4 +-
 packages/scaffold-config/src/frameworks.ts    |  14 +-
 .../test/unit/supportFile.spec.ts             |  20 +-
 .../component_testing_spec.ts.js              | 449 +-----------------
 .../react/cypress/support/component.js        |   2 +-
 .../runner-specs/cypress/support/component.js |   2 +-
 .../src/NewComponent.spec.jsx                 |   2 +-
 .../src/TestComponent.spec.jsx                |   2 +-
 .../vite/cypress/support/component.js         |   2 +-
 .../webpack/cypress/support/component.js      |   2 +-
 .../cypress/support/component.ts              |   2 +-
 .../components/button.cy.jsx                  |   2 +-
 .../components/button.cy.jsx                  |   2 +-
 .../no-specs/cypress/support/component.js     |   2 +-
 .../protocol/cypress/support/component.ts     |   2 +-
 .../react-vite-ts-configured/src/App.cy.tsx   |   2 +-
 .../react18/cypress/support/component.js      |   2 +-
 .../react18/src/UsingLegacyMount.cy.jsx       |  23 -
 .../projects/tailwind-vite/src/App.cy.jsx     |   2 +-
 .../vite-simple/cypress/support/component.js  |   2 +-
 .../src/relative-url.cy.jsx                   |   2 +-
 .../webpack5_wds4-react/src/App.cy.jsx        |   2 +-
 .../webpack5_wds5-react/src/App.cy.jsx        |   2 +-
 system-tests/test/component_testing_spec.ts   |   4 +-
 yarn.lock                                     | 217 ++-------
 91 files changed, 619 insertions(+), 2050 deletions(-)
 rename npm/react/cypress/component/advanced/mocking-axios/{3-users-api.cy.jsx => 2-users-api.cy.jsx} (89%)
 create mode 100644 npm/react/cypress/component/advanced/mocking-axios/2-users-api.jsx
 delete mode 100644 npm/react/cypress/component/advanced/mocking-axios/2-users-named.cy.jsx
 delete mode 100644 npm/react/cypress/component/advanced/mocking-axios/2-users-named.jsx
 delete mode 100644 npm/react/cypress/component/advanced/mocking-axios/3-users-api.jsx
 delete mode 100644 npm/react/cypress/component/basic/enzyme/README.md
 delete mode 100644 npm/react/cypress/component/basic/enzyme/context.cy.jsx
 delete mode 100644 npm/react/cypress/component/basic/enzyme/props.cy.jsx
 delete mode 100644 npm/react/cypress/component/basic/enzyme/simple-component.jsx
 delete mode 100644 npm/react/cypress/component/basic/enzyme/simple-context.jsx
 delete mode 100644 npm/react/cypress/component/basic/enzyme/state.cy.jsx
 delete mode 100644 npm/react/cypress/component/basic/unmount/unmount.cy.jsx
 delete mode 100644 npm/react18/.eslintignore
 delete mode 100644 npm/react18/.releaserc.js
 delete mode 100644 npm/react18/CHANGELOG.md
 delete mode 100644 npm/react18/README.md
 delete mode 100644 npm/react18/package.json
 delete mode 100644 npm/react18/rollup.config.mjs
 delete mode 100644 npm/react18/src/index.ts
 delete mode 100644 npm/react18/tsconfig.json
 delete mode 100644 system-tests/projects/react18/src/UsingLegacyMount.cy.jsx

diff --git a/.circleci/cache-version.txt b/.circleci/cache-version.txt
index 0f616640a769..07249903be9c 100644
--- a/.circleci/cache-version.txt
+++ b/.circleci/cache-version.txt
@@ -1,3 +1,3 @@
 # Bump this version to force CI to re-create the cache from scratch.
 
-11-07-24-vue-cli-service-removal
+11-07-24-react-16-17-removal
diff --git a/.circleci/workflows.yml b/.circleci/workflows.yml
index 31a194b14dab..1e29a0dc3da1 100644
--- a/.circleci/workflows.yml
+++ b/.circleci/workflows.yml
@@ -30,7 +30,7 @@ mainBuildFilters: &mainBuildFilters
         - /^release\/\d+\.\d+\.\d+$/
         # use the following branch as well to ensure that v8 snapshot cache updates are fully tested
         - 'update-v8-snapshot-cache-on-develop'
-        - 'breaking/remove_vue_cli_service'
+        - 'breaking/remove_react_16_17_merge_react18_harness_upstream'
         - 'publish-binary'
 
 # usually we don't build Mac app - it takes a long time
@@ -42,7 +42,7 @@ macWorkflowFilters: &darwin-workflow-filters
     - equal: [ develop, << pipeline.git.branch >> ]
     # use the following branch as well to ensure that v8 snapshot cache updates are fully tested
     - equal: [ 'update-v8-snapshot-cache-on-develop', << pipeline.git.branch >> ]
-    - equal: [ 'breaking/remove_vue_cli_service', << pipeline.git.branch >> ]
+    - equal: [ 'breaking/remove_react_16_17_merge_react18_harness_upstream', << pipeline.git.branch >> ]
     - matches:
         pattern: /^release\/\d+\.\d+\.\d+$/
         value: << pipeline.git.branch >>
@@ -53,7 +53,7 @@ linuxArm64WorkflowFilters: &linux-arm64-workflow-filters
     - equal: [ develop, << pipeline.git.branch >> ]
     # use the following branch as well to ensure that v8 snapshot cache updates are fully tested
     - equal: [ 'update-v8-snapshot-cache-on-develop', << pipeline.git.branch >> ]
-    - equal: [ 'breaking/remove_vue_cli_service', << pipeline.git.branch >> ]
+    - equal: [ 'breaking/remove_react_16_17_merge_react18_harness_upstream', << pipeline.git.branch >> ]
     - matches:
         pattern: /^release\/\d+\.\d+\.\d+$/
         value: << pipeline.git.branch >>
@@ -76,7 +76,7 @@ windowsWorkflowFilters: &windows-workflow-filters
     - equal: [ develop, << pipeline.git.branch >> ]
     # use the following branch as well to ensure that v8 snapshot cache updates are fully tested
     - equal: [ 'update-v8-snapshot-cache-on-develop', << pipeline.git.branch >> ]
-    - equal: [ 'breaking/remove_vue_cli_service', << pipeline.git.branch >> ]
+    - equal: [ 'breaking/remove_react_16_17_merge_react18_harness_upstream', << pipeline.git.branch >> ]
     - matches:
         pattern: /^release\/\d+\.\d+\.\d+$/
         value: << pipeline.git.branch >>
@@ -152,7 +152,7 @@ commands:
           name: Set environment variable to determine whether or not to persist artifacts
           command: |
             echo "Setting SHOULD_PERSIST_ARTIFACTS variable"
-            echo 'if ! [[ "$CIRCLE_BRANCH" != "develop" && "$CIRCLE_BRANCH" != "release/"* && "$CIRCLE_BRANCH" != "breaking/remove_vue_cli_service" ]]; then
+            echo 'if ! [[ "$CIRCLE_BRANCH" != "develop" && "$CIRCLE_BRANCH" != "release/"* && "$CIRCLE_BRANCH" != "breaking/remove_react_16_17_merge_react18_harness_upstream" ]]; then
                 export SHOULD_PERSIST_ARTIFACTS=true
             fi' >> "$BASH_ENV"
   # You must run `setup_should_persist_artifacts` command and be using bash before running this command
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 71f07af48ac9..ccf4888e233c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,7 +5,6 @@
 - [`@cypress/eslint-plugin-dev`](https://github.com/cypress-io/cypress/blob/develop/npm/eslint-plugin-dev/CHANGELOG.md)
 - [`@cypress/mount-utils`](https://github.com/cypress-io/cypress/blob/develop/npm/mount-utils/CHANGELOG.md)
 - [`@cypress/react`](https://github.com/cypress-io/cypress/blob/develop/npm/react/CHANGELOG.md)
-- [`@cypress/react18`](https://github.com/cypress-io/cypress/blob/develop/npm/react18/CHANGELOG.md)
 - [`@cypress/svelte`](https://github.com/cypress-io/cypress/blob/develop/npm/svelte/CHANGELOG.md)
 - [`@cypress/vite-dev-server`](https://github.com/cypress-io/cypress/blob/develop/npm/vite-dev-server/CHANGELOG.md)
 - [`@cypress/vue`](https://github.com/cypress-io/cypress/blob/develop/npm/vue/CHANGELOG.md)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 530134c6218f..2077d1367b5c 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -186,7 +186,6 @@ Here is a list of the npm packages in this repository:
  | [grep](./npm/grep)                                       | `@cypress/grep`                     | Filter tests using substring                        |
  | [mount-utils](./npm/mount-utils)                       | `@cypress/mount-utils`             | Common functionality for Vue/React/Angular adapters. |
  | [react](./npm/react)                                   | `@cypress/react`                   | Cypress component testing for React.             |
- | [react18](./npm/react18)                               | `@cypress/react18`                   | Cypress component testing for React 18.           |
  | [schematic](./npm/cypress-schematic)                   | `@cypress/schematic`            | Official Angular Schematic and Builder for the Angular CLI.|
  | [svelte](./npm/svelte)                               | `@cypress/svelte`                   | Cypress component testing for Svelte.           |
  | [vite-dev-server](./npm/vite-dev-server)     | `@cypress/vite-dev-server`    | Vite powered dev server for Component Testing.                  |
diff --git a/cli/.eslintignore b/cli/.eslintignore
index 9c171ae7d57e..90471aa76fd3 100644
--- a/cli/.eslintignore
+++ b/cli/.eslintignore
@@ -11,7 +11,6 @@ package.json
 # these are all copied from dist'd builds from the individual libs
 /angular
 /react
-/react18
 /vue
 /svelte
 /mount-utils
\ No newline at end of file
diff --git a/cli/CHANGELOG.md b/cli/CHANGELOG.md
index 331fe0f4460f..699fe3d352a7 100644
--- a/cli/CHANGELOG.md
+++ b/cli/CHANGELOG.md
@@ -17,11 +17,13 @@ _Released 12/3/2024 (PENDING)_
 - It is no longer possible to make a `fetch` or `XMLHttpRequest` request from the `about:blank` page in Electron (i.e. `cy.window().then((win) => win.fetch('<some-url>')`). You must use `cy.request` instead or perform some form of initial navigation via `cy.visit()`. Addressed in [#29547](https://github.com/cypress-io/cypress/pull/30394).
 - `@cypress/webpack-dev-server` no longer supports `webpack-dev-server` version 3. Additionally, `@cypress/webpack-dev-server` now ships with `webpack-dev-server` version 5 by default. `webpack-dev-server` version 4 will need to be installed along side Cypress if you are still using `webpack` version 4. Addresses [#29308](https://github.com/cypress-io/cypress/issues/29308), [#30347](https://github.com/cypress-io/cypress/issues/30347), and [#30141](https://github.com/cypress-io/cypress/issues/30141).
 - `@cypress/vite-dev-server` no longer supports `vite` versions 2 and 3. Addresses [#29377](https://github.com/cypress-io/cypress/issues/29377) and [#29378](https://github.com/cypress-io/cypress/issues/29378).
-- Cypress Component Testing no longer supports `Nuxt.js` version 2. Addresses [#30468](https://github.com/cypress-io/cypress/issues/30468).
-- Cypress Component Testing no longer supports `Vue` version 2. Addresses [#30295](https://github.com/cypress-io/cypress/issues/30295).
+- Cypress Component Testing no longer supports `React` versions 16 and 17. Addresses [#29607](https://github.com/cypress-io/cypress/issues/29607).
 - Cypress Component Testing no longer supports `Next.js` versions 10, 11, 12, and 13. Addresses [#29583](https://github.com/cypress-io/cypress/issues/29583).
+- Cypress Component Testing no longer supports `Vue` version 2. Addresses [#30295](https://github.com/cypress-io/cypress/issues/30295).
+- Cypress Component Testing no longer supports `Nuxt.js` version 2. Addresses [#30468](https://github.com/cypress-io/cypress/issues/30468).
 - Cypress Component Testing no longer supports `Angular` versions 13, 14, 15, and 16. The minimum supported version is now `17.2.0` in order to fully support Angular [signals](https://angular.dev/guide/signals). Addresses [#29582](https://github.com/cypress-io/cypress/issues/29582). Addressed in [#30539](https://github.com/cypress-io/cypress/pull/30539).
 - Cypress Component Testing no longer supports `Svelte` version 3. Addresses [#30492](https://github.com/cypress-io/cypress/issues/30492).
+- The `cypress/react18` test harness is no longer included in the Cypress binary. Instead, React 18 support is now shipped with `cypress/react`! Addresses [#29607](https://github.com/cypress-io/cypress/issues/29607).
 - The `cypress/angular-signals` test harness is no longer included in the Cypress binary. Instead, signals support is now shipped with `cypress/angular`! This requires `rxjs` to be installed as a `peerDependency`. Addresses [#29606](https://github.com/cypress-io/cypress/issues/29606).
 - Cypress Component Testing no longer supports `create-react-app`. Addresses [#30028](https://github.com/cypress-io/cypress/issues/30028).
 - Cypress Component Testing no longer supports `@vue/cli-service`. Addresses [#30481](https://github.com/cypress-io/cypress/issues/30481).
diff --git a/cli/package.json b/cli/package.json
index 63ae512b0bf7..62377435c439 100644
--- a/cli/package.json
+++ b/cli/package.json
@@ -71,7 +71,6 @@
     "@cypress/grep": "0.0.0-development",
     "@cypress/mount-utils": "0.0.0-development",
     "@cypress/react": "0.0.0-development",
-    "@cypress/react18": "0.0.0-development",
     "@cypress/sinon-chai": "2.9.1",
     "@cypress/svelte": "0.0.0-development",
     "@cypress/vue": "0.0.0-development",
@@ -114,7 +113,6 @@
     "mount-utils",
     "vue",
     "react",
-    "react18",
     "angular",
     "svelte"
   ],
@@ -145,11 +143,6 @@
       "import": "./react/dist/cypress-react.esm-bundler.js",
       "require": "./react/dist/cypress-react.cjs.js"
     },
-    "./react18": {
-      "types": "./react18/dist/index.d.ts",
-      "import": "./react18/dist/cypress-react.esm-bundler.js",
-      "require": "./react18/dist/cypress-react.cjs.js"
-    },
     "./mount-utils": {
       "types": "./mount-utils/dist/index.d.ts",
       "require": "./mount-utils/dist/index.js"
diff --git a/cli/scripts/post-build.js b/cli/scripts/post-build.js
index 4ee23008cf03..e31b9e2cf807 100644
--- a/cli/scripts/post-build.js
+++ b/cli/scripts/post-build.js
@@ -9,7 +9,6 @@ shell.set('-e') // any error is fatal
 const npmModulesToCopy = [
   'mount-utils',
   'react',
-  'react18',
   'vue',
   'angular',
   'svelte',
diff --git a/npm/react/cypress/component/advanced/app-action-example/counter.cy.jsx b/npm/react/cypress/component/advanced/app-action-example/counter.cy.jsx
index 68caae19c867..bd7296290916 100644
--- a/npm/react/cypress/component/advanced/app-action-example/counter.cy.jsx
+++ b/npm/react/cypress/component/advanced/app-action-example/counter.cy.jsx
@@ -20,15 +20,13 @@ describe('Counter with access', () => {
     // the window.counter was set from the Counter's constructor
     cy.window()
     .should('have.property', 'counter')
-    .its('state')
-    .should('deep.equal', { count: 0 })
+    .its('count')
+    .should('equal', 0)
 
     // let's change the state of the component
     cy.window()
     .its('counter')
-    .invoke('setState', {
-      count: 101,
-    })
+    .invoke('setCount', 101)
 
     // the UI should update to reflect the new count
     cy.contains('count: 101').should('be.visible')
diff --git a/npm/react/cypress/component/advanced/app-action-example/counter.jsx b/npm/react/cypress/component/advanced/app-action-example/counter.jsx
index b300ff3106e5..1aed4d619089 100644
--- a/npm/react/cypress/component/advanced/app-action-example/counter.jsx
+++ b/npm/react/cypress/component/advanced/app-action-example/counter.jsx
@@ -1,34 +1,28 @@
-import React from 'react'
+import React, { useState } from 'react'
 
-export class Counter extends React.Component {
-  constructor (props) {
-    super(props)
-    this.state = {
-      count: 0,
-    }
+export function Counter () {
+  const [count, setCount] = useState(0)
 
-    if (window.Cypress) {
-      // if this component is mounted from inside Cypress Test Runner
-      // then expose the reference to this instance
-      // to allow controlling it from tests
-      console.log(
-        'set window.counter to this component in window',
-        window.location.pathname,
-      )
+  if (window.Cypress) {
+    // if this component is mounted from inside Cypress Test Runner
+    // then expose the reference to this instance
+    // to allow controlling it from tests
+    console.log(
+      'set window.counter to this component in window',
+      window.location.pathname,
+    )
 
-      window.counter = this
-    } else {
-      console.log('running outside Cypress')
+    window.counter = {
+      count,
+      setCount,
     }
+  } else {
+    console.log('running outside Cypress')
   }
 
-  click = () => {
-    this.setState({
-      count: this.state.count + 1,
-    })
+  function click () {
+    setCount(count + 1)
   }
 
-  render () {
-    return <p onClick={this.click}>count: {this.state.count}</p>
-  }
+  return <p onClick={click}>count: {count}</p>
 }
diff --git a/npm/react/cypress/component/advanced/context/App.jsx b/npm/react/cypress/component/advanced/context/App.jsx
index 4620e6c38816..965e0a06815c 100644
--- a/npm/react/cypress/component/advanced/context/App.jsx
+++ b/npm/react/cypress/component/advanced/context/App.jsx
@@ -2,15 +2,13 @@ import React from 'react'
 import { ThemeContext } from './context'
 import { Toolbar } from './Toolbar.jsx'
 
-export default class App extends React.Component {
-  render () {
-    // Use a Provider to pass the current theme to the tree below.
-    // Any component can read it, no matter how deep it is.
-    // In this example, we're passing "dark" as the current value.
-    return (
-      <ThemeContext.Provider value="dark">
-        <Toolbar />
-      </ThemeContext.Provider>
-    )
-  }
+export default function App () {
+  // Use a Provider to pass the current theme to the tree below.
+  // Any component can read it, no matter how deep it is.
+  // In this example, we're passing "dark" as the current value.
+  return (
+    <ThemeContext.Provider value="dark">
+      <Toolbar />
+    </ThemeContext.Provider>
+  )
 }
diff --git a/npm/react/cypress/component/advanced/mocking-axios/1-users.jsx b/npm/react/cypress/component/advanced/mocking-axios/1-users.jsx
index 0b7081db11d3..0e896fa1d0ed 100644
--- a/npm/react/cypress/component/advanced/mocking-axios/1-users.jsx
+++ b/npm/react/cypress/component/advanced/mocking-axios/1-users.jsx
@@ -1,36 +1,29 @@
-import React from 'react'
+import React, { useState, useEffect } from 'react'
 // import the entire axios module
 // later we can use axios.get to make requests
 import axios from 'axios'
 
-export class Users extends React.Component {
-  constructor (props) {
-    super(props)
-    this.state = {
-      users: [],
-    }
-  }
+export function Users () {
+  const [users, setUsers] = useState([])
 
-  componentDidMount () {
-    axios
-    .get('https://jsonplaceholder.cypress.io/users?_limit=3')
-    .then((response) => {
-      // JSON responses are automatically parsed.
-      this.setState({
-        users: response.data,
-      })
-    })
-  }
+  const getUsers = async () => {
+    const response = await axios.get('https://jsonplaceholder.cypress.io/users?_limit=3')
+    // JSON responses are automatically parsed.
 
-  render () {
-    return (
-      <div>
-        {this.state.users.map((user) => (
-          <li key={user.id}>
-            <strong>{user.id}</strong> - {user.name}
-          </li>
-        ))}
-      </div>
-    )
+    setUsers(response.data)
   }
+
+  useEffect(() => {
+    getUsers()
+  }, [])
+
+  return (
+    <div>
+      {users.map((user) => (
+        <li key={user.id}>
+          <strong>{user.id}</strong> - {user.name}
+        </li>
+      ))}
+    </div>
+  )
 }
diff --git a/npm/react/cypress/component/advanced/mocking-axios/3-users-api.cy.jsx b/npm/react/cypress/component/advanced/mocking-axios/2-users-api.cy.jsx
similarity index 89%
rename from npm/react/cypress/component/advanced/mocking-axios/3-users-api.cy.jsx
rename to npm/react/cypress/component/advanced/mocking-axios/2-users-api.cy.jsx
index 456c05112e1e..baa74cf22355 100644
--- a/npm/react/cypress/component/advanced/mocking-axios/3-users-api.cy.jsx
+++ b/npm/react/cypress/component/advanced/mocking-axios/2-users-api.cy.jsx
@@ -1,8 +1,8 @@
 /// <reference types="cypress" />
 import React from 'react'
 import { mount } from '@cypress/react'
-import { Users } from './3-users-api.jsx'
-import * as axios from './axios-api'
+import { Users } from './2-users-api.jsx'
+import * as axios from './axios-api.jsx'
 
 describe('Mocking wrapped Axios', () => {
   it('shows real users', () => {
diff --git a/npm/react/cypress/component/advanced/mocking-axios/2-users-api.jsx b/npm/react/cypress/component/advanced/mocking-axios/2-users-api.jsx
new file mode 100644
index 000000000000..96fcbc13c075
--- /dev/null
+++ b/npm/react/cypress/component/advanced/mocking-axios/2-users-api.jsx
@@ -0,0 +1,29 @@
+import React, { useState, useEffect } from 'react'
+// import wrapped Axios method
+import axiosApi from './axios-api.jsx'
+
+export function Users () {
+  const [users, setUsers] = useState([])
+
+  const getUsers = async () => {
+    console.log({ axiosApi })
+    const response = await axiosApi.get('https://jsonplaceholder.cypress.io/users?_limit=3')
+    // JSON responses are automatically parsed.
+
+    setUsers(response.data)
+  }
+
+  useEffect(() => {
+    getUsers()
+  }, [])
+
+  return (
+    <div>
+      {users.map((user) => (
+        <li key={user.id}>
+          <strong>{user.id}</strong> - {user.name}
+        </li>
+      ))}
+    </div>
+  )
+}
diff --git a/npm/react/cypress/component/advanced/mocking-axios/2-users-named.cy.jsx b/npm/react/cypress/component/advanced/mocking-axios/2-users-named.cy.jsx
deleted file mode 100644
index bbb76f2db738..000000000000
--- a/npm/react/cypress/component/advanced/mocking-axios/2-users-named.cy.jsx
+++ /dev/null
@@ -1,36 +0,0 @@
-/// <reference types="cypress" />
-import React from 'react'
-import { mount } from '@cypress/react'
-import { Users } from './2-users-named.jsx'
-import axios from 'axios'
-
-describe('Mocking Axios named import get', () => {
-  it('shows real users', () => {
-    mount(<Users />)
-    cy.get('li').should('have.length', 3)
-  })
-
-  // TODO: Support stubbing ES Modules
-  it.skip('mocks get', () => {
-    cy.stub(axios, 'get')
-    .resolves({
-      data: [
-        {
-          id: 101,
-          name: 'Test User',
-        },
-      ],
-    })
-    .as('get')
-
-    mount(<Users />)
-    // only the test user should be shown
-    cy.get('li').should('have.length', 1)
-    cy.get('@get').should('have.been.called')
-  })
-
-  it('restores the original method', () => {
-    mount(<Users />)
-    cy.get('li').should('have.length', 3)
-  })
-})
diff --git a/npm/react/cypress/component/advanced/mocking-axios/2-users-named.jsx b/npm/react/cypress/component/advanced/mocking-axios/2-users-named.jsx
deleted file mode 100644
index 11be902cda20..000000000000
--- a/npm/react/cypress/component/advanced/mocking-axios/2-users-named.jsx
+++ /dev/null
@@ -1,33 +0,0 @@
-import React from 'react'
-// use named import "get" from the module
-import { get } from 'axios'
-
-export class Users extends React.Component {
-  constructor (props) {
-    super(props)
-    this.state = {
-      users: [],
-    }
-  }
-
-  componentDidMount () {
-    get('https://jsonplaceholder.cypress.io/users?_limit=3').then((response) => {
-      // JSON responses are automatically parsed.
-      this.setState({
-        users: response.data,
-      })
-    })
-  }
-
-  render () {
-    return (
-      <div>
-        {this.state.users.map((user) => (
-          <li key={user.id}>
-            <strong>{user.id}</strong> - {user.name}
-          </li>
-        ))}
-      </div>
-    )
-  }
-}
diff --git a/npm/react/cypress/component/advanced/mocking-axios/3-users-api.jsx b/npm/react/cypress/component/advanced/mocking-axios/3-users-api.jsx
deleted file mode 100644
index 3d7becfc5422..000000000000
--- a/npm/react/cypress/component/advanced/mocking-axios/3-users-api.jsx
+++ /dev/null
@@ -1,34 +0,0 @@
-import React from 'react'
-// import wrapped Axios method
-import axiosApi from './axios-api'
-
-export class Users extends React.Component {
-  constructor (props) {
-    super(props)
-    this.state = {
-      users: [],
-    }
-  }
-
-  componentDidMount () {
-    console.log({ axiosApi })
-    axiosApi.get('https://jsonplaceholder.cypress.io/users?_limit=3').then((response) => {
-      // JSON responses are automatically parsed.
-      this.setState({
-        users: response.data,
-      })
-    })
-  }
-
-  render () {
-    return (
-      <div>
-        {this.state.users.map((user) => (
-          <li key={user.id}>
-            <strong>{user.id}</strong> - {user.name}
-          </li>
-        ))}
-      </div>
-    )
-  }
-}
diff --git a/npm/react/cypress/component/advanced/renderless/mouse-movement.jsx b/npm/react/cypress/component/advanced/renderless/mouse-movement.jsx
index 8e838c58b208..609337969ec5 100644
--- a/npm/react/cypress/component/advanced/renderless/mouse-movement.jsx
+++ b/npm/react/cypress/component/advanced/renderless/mouse-movement.jsx
@@ -1,52 +1,44 @@
 // https://medium.com/@pierrehedkvist/renderless-components-in-react-8d663746314c
-import React from 'react'
+// eslint-disable-next-line no-unused-vars
+import React, { useState, useEffect } from 'react'
 import PropTypes from 'prop-types'
 
-export default class MouseMovement extends React.Component {
-  constructor (props) {
-    console.log('MouseMovement constructor')
-    super(props)
-    this.state = {
-      timer: undefined,
-    }
-
-    this.timeout = this.timeout.bind(this)
-    this.onMouseMove = this.onMouseMove.bind(this)
-  }
+export default function MouseMovement ({ onMoved }) {
+  const [timer, setTimer] = useState(undefined)
 
-  componentWillMount () {
-    console.log('MouseMovement componentWillMount')
-    document.addEventListener('mousemove', this.onMouseMove)
-    const timer = setTimeout(this.timeout, 4000)
+  function onMouseMove () {
+    console.log('MouseMovement onMouseMove')
+    clearTimeout(timer)
+    const timerNew = setTimeout(timeout, 4000)
 
-    this.setState({ timer })
+    setTimer(timerNew)
+    onMoved(true)
   }
 
-  componentWillUnmount () {
-    console.log('MouseMovement componentWillUnmount')
-    document.removeEventListener('mousemove', this.onMouseMove)
-    clearTimeout(this.state.timer)
-    this.setState({ timer: undefined })
+  function timeout () {
+    console.log('timeout')
+    clearTimeout(timer)
+    onMoved(false)
   }
 
-  onMouseMove () {
-    console.log('MouseMovement onMouseMove')
-    clearTimeout(this.state.timer)
-    const timer = setTimeout(this.timeout, 4000)
+  useEffect(() => {
+    // Anything in here is fired on component mount.
+    console.log('MouseMovement componentWillMount')
+    document.addEventListener('mousemove', onMouseMove)
+    const timerNew = setTimeout(timeout, 4000)
 
-    this.setState({ timer })
-    this.props.onMoved(true)
-  }
+    setTimer(timerNew)
 
-  timeout () {
-    console.log('timeout')
-    clearTimeout(this.state.timer)
-    this.props.onMoved(false)
-  }
+    return () => {
+      // Anything in here is fired on component unmount.
+      console.log('MouseMovement componentWillUnmount')
+      document.removeEventListener('mousemove', onMouseMove)
+      clearTimeout(timer)
+      setTimer(undefined)
+    }
+  })
 
-  render () {
-    return null
-  }
+  return null
 }
 
 MouseMovement.propTypes = {
diff --git a/npm/react/cypress/component/advanced/renderless/mouse.cy.jsx b/npm/react/cypress/component/advanced/renderless/mouse.cy.jsx
index 670d3dc92214..4bd6984dac03 100644
--- a/npm/react/cypress/component/advanced/renderless/mouse.cy.jsx
+++ b/npm/react/cypress/component/advanced/renderless/mouse.cy.jsx
@@ -5,14 +5,6 @@ import MouseMovement from './mouse-movement'
 
 describe('Renderless component', () => {
   it('works', () => {
-    // let's also spy on "console.log" calls
-    // to make sure the entire sequence of calls happens
-    cy.window()
-    .its('console')
-    .then((console) => {
-      cy.spy(console, 'log').as('log')
-    })
-
     const onMoved = cy.stub()
 
     mount(<MouseMovement onMoved={onMoved} />)
@@ -23,27 +15,7 @@ describe('Renderless component', () => {
       expect(onMoved).to.have.been.calledWith(true)
     })
 
-    // mount something else to trigger unmount
+    // mount something else to trigger unmount and stop log flow
     mount(<div>Test Component</div>)
-
-    cy.get('@log')
-    .its('callCount')
-    .should('equal', 4)
-
-    cy.get('@log')
-    .invoke('getCalls')
-    .then((calls) => {
-      return calls.map((call) => {
-        console.log('one', call.args[0])
-
-        return call.args[0]
-      })
-    })
-    .should('deep.equal', [
-      'MouseMovement constructor',
-      'MouseMovement componentWillMount',
-      'MouseMovement onMouseMove',
-      'MouseMovement componentWillUnmount',
-    ])
   })
 })
diff --git a/npm/react/cypress/component/advanced/set-timeout-example/App.jsx b/npm/react/cypress/component/advanced/set-timeout-example/App.jsx
index 6c4aa515a9a0..6346e91ba177 100644
--- a/npm/react/cypress/component/advanced/set-timeout-example/App.jsx
+++ b/npm/react/cypress/component/advanced/set-timeout-example/App.jsx
@@ -1,35 +1,31 @@
-import React, { Component } from 'react'
+import React, { useState, useEffect } from 'react'
 import './App.css'
 import logo from './logo.svg'
 import LoadingIndicator from './LoadingIndicator'
 
-class App extends Component {
-  state = {
-    isLoading: true,
-  }
+function App () {
+  const [isLoading, setIsLoading] = useState(true)
 
-  componentDidMount () {
-    this._timer = setTimeout(() => this.setState({ isLoading: false }), 2000)
-  }
+  useEffect(() => {
+    const _timer = setTimeout(() => setIsLoading(false), 2000)
 
-  componentWillUnmount () {
-    clearTimeout(this._timer)
-  }
+    return () => {
+      clearTimeout(_timer)
+    }
+  })
 
-  render () {
-    return (
-      <div className="App">
-        <header className="App-header">
-          <img src={logo} className="App-logo" alt="logo" />
-          <h1 className="App-title">Welcome to React</h1>
-        </header>
-        <pre>isLoading: {String(this.state.isLoading)}</pre>
-        <LoadingIndicator isLoading={this.state.isLoading}>
-          <div>ahoy!</div>
-        </LoadingIndicator>
-      </div>
-    )
-  }
+  return (
+    <div className="App">
+      <header className="App-header">
+        <img src={logo} className="App-logo" alt="logo" />
+        <h1 className="App-title">Welcome to React</h1>
+      </header>
+      <pre>isLoading: {String(isLoading)}</pre>
+      <LoadingIndicator isLoading={isLoading}>
+        <div>ahoy!</div>
+      </LoadingIndicator>
+    </div>
+  )
 }
 
 export default App
diff --git a/npm/react/cypress/component/advanced/set-timeout-example/LoadingIndicator.jsx b/npm/react/cypress/component/advanced/set-timeout-example/LoadingIndicator.jsx
index 0c6cdfec36dc..b5efe7a250d9 100644
--- a/npm/react/cypress/component/advanced/set-timeout-example/LoadingIndicator.jsx
+++ b/npm/react/cypress/component/advanced/set-timeout-example/LoadingIndicator.jsx
@@ -1,37 +1,26 @@
-import React, { Component } from 'react'
-import PropTypes from 'prop-types'
+import React, { useState, useEffect } from 'react'
 
-export default class LoadingIndicator extends Component {
-  static propTypes = {
-    isLoading: PropTypes.bool.isRequired,
-  }
-
-  state = {
-    isPastDelay: false,
-  }
+export default function LoadingIndicator ({ isLoading, children }) {
+  const [isPastDelay, setIsPastDelay] = useState(false)
 
-  componentDidMount () {
-    console.log('component did mount')
-    this._delayTimer = setTimeout(() => {
+  useEffect(() => {
+    const _delayTimer = setTimeout(() => {
       console.log('2000ms passed')
-      this.setState({ isPastDelay: true })
+      setIsPastDelay(true)
     }, 2000)
-  }
 
-  componentWillUnmount () {
-    console.log('componentWillUnmount')
-    clearTimeout(this._delayTimer)
-  }
-
-  render () {
-    if (this.props.isLoading) {
-      if (!this.state.isPastDelay) {
-        return null
-      }
+    return () => {
+      clearTimeout(_delayTimer)
+    }
+  })
 
-      return <div>loading...</div>
+  if (isLoading) {
+    if (!isPastDelay) {
+      return null
     }
 
-    return this.props.children
+    return <div>loading...</div>
   }
+
+  return children
 }
diff --git a/npm/react/cypress/component/advanced/timers/card-without-effect.jsx b/npm/react/cypress/component/advanced/timers/card-without-effect.jsx
index e85bc2ef301d..e1b40c692353 100644
--- a/npm/react/cypress/component/advanced/timers/card-without-effect.jsx
+++ b/npm/react/cypress/component/advanced/timers/card-without-effect.jsx
@@ -1,5 +1,6 @@
 import React, { Component } from 'react'
 
+// Class components will be removed in a future release of React 18+. Until then, this example will serve as a class component example
 export default class Card extends Component {
   componentDidMount () {
     this._timeoutID = setTimeout(() => {
diff --git a/npm/react/cypress/component/advanced/tutorial/shopping-list.jsx b/npm/react/cypress/component/advanced/tutorial/shopping-list.jsx
index b2ea82ee7b94..7dec846617b5 100644
--- a/npm/react/cypress/component/advanced/tutorial/shopping-list.jsx
+++ b/npm/react/cypress/component/advanced/tutorial/shopping-list.jsx
@@ -1,16 +1,14 @@
 import React from 'react'
 
-export default class ShoppingList extends React.Component {
-  render () {
-    return (
-      <div className="shopping-list">
-        <h1>Shopping List for {this.props.name}</h1>
-        <ul>
-          <li>Instagram</li>
-          <li>WhatsApp</li>
-          <li>Oculus</li>
-        </ul>
-      </div>
-    )
-  }
+export default function ShoppingList ({ name }) {
+  return (
+    <div className="shopping-list">
+      <h1>Shopping List for {name}</h1>
+      <ul>
+        <li>Instagram</li>
+        <li>WhatsApp</li>
+        <li>Oculus</li>
+      </ul>
+    </div>
+  )
 }
diff --git a/npm/react/cypress/component/advanced/tutorial/square.cy.jsx b/npm/react/cypress/component/advanced/tutorial/square.cy.jsx
index 33e70df52aaf..57aaa5a3d17c 100644
--- a/npm/react/cypress/component/advanced/tutorial/square.cy.jsx
+++ b/npm/react/cypress/component/advanced/tutorial/square.cy.jsx
@@ -1,27 +1,17 @@
 /// <reference types="cypress" />
-import React from 'react'
+import React, { useState } from 'react'
 import { mount } from '@cypress/react'
 import './tic-tac-toe.css'
 
 // let's put React component right in the spec file
-class Square extends React.Component {
-  constructor (props) {
-    super(props)
-    this.state = {
-      value: null,
-    }
-  }
+export default function Square ({ value: valueAsProp }) {
+  const [valueAsState, setValueAsState] = useState(null)
 
-  render () {
-    return (
-      <button
-        className="square"
-        onClick={() => this.setState({ value: this.props.value })}
-      >
-        {this.state.value}
-      </button>
-    )
-  }
+  return (
+    <button className="square" onClick={() => setValueAsState(valueAsProp)}>
+      {valueAsState}
+    </button>
+  )
 }
 
 describe('Square', () => {
diff --git a/npm/react/cypress/component/advanced/tutorial/tic-tac-toe.cy.jsx b/npm/react/cypress/component/advanced/tutorial/tic-tac-toe.cy.jsx
index c4b93f89803c..57bfea3cc867 100644
--- a/npm/react/cypress/component/advanced/tutorial/tic-tac-toe.cy.jsx
+++ b/npm/react/cypress/component/advanced/tutorial/tic-tac-toe.cy.jsx
@@ -3,7 +3,7 @@
 /// <reference types="cypress" />
 import React from 'react'
 import { mount } from '@cypress/react'
-import { Game } from './tic-tac-toe.jsx'
+import Game from './tic-tac-toe.jsx'
 import './tic-tac-toe.css'
 
 describe('Tic Tac Toe', () => {
diff --git a/npm/react/cypress/component/advanced/tutorial/tic-tac-toe.jsx b/npm/react/cypress/component/advanced/tutorial/tic-tac-toe.jsx
index 35c4a704c017..b7b0f2f76013 100644
--- a/npm/react/cypress/component/advanced/tutorial/tic-tac-toe.jsx
+++ b/npm/react/cypress/component/advanced/tutorial/tic-tac-toe.jsx
@@ -1,115 +1,125 @@
-// entire game from the tutorial inside the spec for simplicity
-// the code taken from https://codepen.io/gaearon/pen/LyyXgK
-import React from 'react'
+import React, { useState } from 'react'
 
-export function calculateWinner (squares) {
-  const lines = [
-    [0, 1, 2],
-    [3, 4, 5],
-    [6, 7, 8],
-    [0, 3, 6],
-    [1, 4, 7],
-    [2, 5, 8],
-    [0, 4, 8],
-    [2, 4, 6],
-  ]
+function Square ({ value, onSquareClick }) {
+  return (
+    <button className="square" onClick={onSquareClick}>
+      {value}
+    </button>
+  )
+}
 
-  for (let i = 0; i < lines.length; i++) {
-    const [a, b, c] = lines[i]
+export function Board ({ xIsNext, squares, onPlay }) {
+  function handleClick (i) {
+    if (calculateWinner(squares) || squares[i]) {
+      return
+    }
 
-    if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
-      return squares[a]
+    const nextSquares = squares.slice()
+
+    if (xIsNext) {
+      nextSquares[i] = 'X'
+    } else {
+      nextSquares[i] = 'O'
     }
+
+    onPlay(nextSquares)
   }
 
-  return null
-}
+  const winner = calculateWinner(squares)
+  let status
+
+  if (winner) {
+    status = `Winner: ${ winner}`
+  } else {
+    status = `Next player: ${ xIsNext ? 'X' : 'O'}`
+  }
 
-function Square (props) {
   return (
-    <button className="square" onClick={props.onClick}>
-      {props.value}
-    </button>
+    <>
+      <div className="status">{status}</div>
+      <div className="board-row">
+        <Square value={squares[0]} onSquareClick={() => handleClick(0)} />
+        <Square value={squares[1]} onSquareClick={() => handleClick(1)} />
+        <Square value={squares[2]} onSquareClick={() => handleClick(2)} />
+      </div>
+      <div className="board-row">
+        <Square value={squares[3]} onSquareClick={() => handleClick(3)} />
+        <Square value={squares[4]} onSquareClick={() => handleClick(4)} />
+        <Square value={squares[5]} onSquareClick={() => handleClick(5)} />
+      </div>
+      <div className="board-row">
+        <Square value={squares[6]} onSquareClick={() => handleClick(6)} />
+        <Square value={squares[7]} onSquareClick={() => handleClick(7)} />
+        <Square value={squares[8]} onSquareClick={() => handleClick(8)} />
+      </div>
+    </>
   )
 }
 
-export class Board extends React.Component {
-  constructor (props) {
-    super(props)
-    this.state = {
-      squares: Array(9).fill(null),
-      xIsNext: true,
-    }
-  }
+export default function Game () {
+  const [history, setHistory] = useState([Array(9).fill(null)])
+  const [currentMove, setCurrentMove] = useState(0)
+  const xIsNext = currentMove % 2 === 0
+  const currentSquares = history[currentMove]
 
-  handleClick (i) {
-    const squares = this.state.squares.slice()
+  function handlePlay (nextSquares) {
+    const nextHistory = [...history.slice(0, currentMove + 1), nextSquares]
 
-    if (calculateWinner(squares) || squares[i]) {
-      return
-    }
-
-    squares[i] = this.state.xIsNext ? 'X' : 'O'
-    this.setState({
-      squares,
-      xIsNext: !this.state.xIsNext,
-    })
+    setHistory(nextHistory)
+    setCurrentMove(nextHistory.length - 1)
   }
 
-  renderSquare (i) {
-    return (
-      <Square
-        value={this.state.squares[i]}
-        onClick={() => this.handleClick(i)}
-      />
-    )
+  function jumpTo (nextMove) {
+    setCurrentMove(nextMove)
   }
 
-  render () {
-    const winner = calculateWinner(this.state.squares)
-    let status
+  const moves = history.map((squares, move) => {
+    let description
 
-    if (winner) {
-      status = `Winner: ${winner}`
+    if (move > 0) {
+      description = `Go to move #${ move}`
     } else {
-      status = `Next player: ${this.state.xIsNext ? 'X' : 'O'}`
+      description = 'Go to game start'
     }
 
     return (
-      <div>
-        <div className="status">{status}</div>
-        <div className="board-row">
-          {this.renderSquare(0)}
-          {this.renderSquare(1)}
-          {this.renderSquare(2)}
-        </div>
-        <div className="board-row">
-          {this.renderSquare(3)}
-          {this.renderSquare(4)}
-          {this.renderSquare(5)}
-        </div>
-        <div className="board-row">
-          {this.renderSquare(6)}
-          {this.renderSquare(7)}
-          {this.renderSquare(8)}
-        </div>
-      </div>
+      <li key={move}>
+        <button onClick={() => jumpTo(move)}>{description}</button>
+      </li>
     )
-  }
-}
+  })
 
-export class Game extends React.Component {
-  render () {
-    return (
-      <div className="game">
-        <div className="game-board">
-          <Board />
-        </div>
-        <div className="game-info">
-          <div>{/* status */}</div>
-          <ol>{/* TODO */}</ol>
-        </div>
+  return (
+    <div className="game">
+      <div className="game-board">
+        <Board xIsNext={xIsNext} squares={currentSquares} onPlay={handlePlay} />
       </div>
-    )
+      <div className="game-info">
+        <ol>{moves}</ol>
+      </div>
+    </div>
+  )
+}
+
+export function calculateWinner (squares) {
+  const lines = [
+    [0, 1, 2],
+    [3, 4, 5],
+    [6, 7, 8],
+    [0, 3, 6],
+    [1, 4, 7],
+    [2, 5, 8],
+    [0, 4, 8],
+    [2, 4, 6],
+  ]
+
+  for (let i = 0; i < lines.length; i++) {
+    const [a, b, c] = lines[i]
+
+    if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
+      return squares[a]
+    }
   }
+
+  return null
 }
diff --git a/npm/react/cypress/component/basic/css/Button.jsx b/npm/react/cypress/component/basic/css/Button.jsx
index f2801f5dc218..69564bb12127 100644
--- a/npm/react/cypress/component/basic/css/Button.jsx
+++ b/npm/react/cypress/component/basic/css/Button.jsx
@@ -1,22 +1,20 @@
 import React from 'react'
 import './Button.css'
 
-export class Button extends React.Component {
-  handleClick () {
-    this.props.clickHandler(this.props.name)
-  }
-
-  render () {
-    const className = [
-      'component-button',
-      this.props.orange ? 'orange' : '',
-      this.props.wide ? 'wide' : '',
-    ]
+export function Button ({ name, orange, wide, clickHandler }) {
+  const className = [
+    'component-button',
+    orange ? 'orange' : '',
+    wide ? 'wide' : '',
+  ]
 
-    return (
-      <div className={className.join(' ').trim()}>
-        <button onClick={this.handleClick.bind(this)}>{this.props.name}</button>
-      </div>
-    )
+  function handleClick () {
+    clickHandler(name)
   }
+
+  return (
+    <div className={className.join(' ').trim()}>
+      <button onClick={handleClick.bind(this)}>{name}</button>
+    </div>
+  )
 }
diff --git a/npm/react/cypress/component/basic/enzyme/README.md b/npm/react/cypress/component/basic/enzyme/README.md
deleted file mode 100644
index 947f0b442ed8..000000000000
--- a/npm/react/cypress/component/basic/enzyme/README.md
+++ /dev/null
@@ -1,98 +0,0 @@
-# Enzyme examples
-
-This folder shows several examples from [Enzyme docs](https://enzymejs.github.io/enzyme/).
-
-In general if you are migrating from Enzyme to `@cypress/react`:
-
-- there is no shallow mounting, only the full mounting. Thus `@cypress/react` has `mount` which is similar to the Enzyme's `render`. It renders the full HTML and CSS output of your component. 
-- you can mock [children components](https://github.com/bahmutov/cypress-react-unit-test/tree/main/cypress/component/advanced/mocking-component) if you want to avoid running "expensive" components during tests
-- the test is running as a "mini" web application. Thus if you want to set a context around component, then set the [context around the component](https://github.com/bahmutov/cypress-react-unit-test/tree/main/cypress/component/advanced/context)
-
-## setState
-
-If you want to change the component's internal state, use the component reference. You can get it by using the special property `ref` when mounting.
-
-```js
-// get the component reference using "ref" prop
-// and place it into the object for Cypress to "wait" for it
-let c = {}
-mount(<Foo id="foo" foo="initial" ref={i => (c.instance = i)} />)
-cy.wrap(c)
-  .its('instance')
-  .invoke('setState', { count: 10 })
-```
-
-See [state-spec.js](state-spec.js) file.
-
-## setProps
-
-There is no direct implementation of `setProps`. If you want to see how the component behaves with different props:
-
-```js
-it('mounts component with new props', () => {
-  mount(<Foo id="foo" foo="initial" />)
-  cy.contains('initial').should('be.visible')
-
-  mount(<Foo id="foo" foo="second" />)
-  cy.contains('second').should('be.visible')
-})
-```
-
-If you want to reuse properties, you can even clone the component
-
-```js
-it('mounts cloned component', () => {
-  const cmp = <Foo id="foo" foo="initial" />
-  mount(cmp)
-  cy.contains('initial').should('be.visible')
-
-  const cloned = Cypress._.cloneDeep(cmp)
-  // change a property, leaving the rest unchanged
-  cloned.props.foo = 'second'
-  mount(cloned)
-  cy.contains('.foo', 'second').should('be.visible')
-})
-```
-
-See [props-spec.js](props-spec.js) file.
-
-## context
-
-Enzyme's `mount` method allows passing the [React context](https://reactjs.org/docs/context.html) as the second argument to the JSX component like `SimpleComponent` below.
-
-```js
-function SimpleComponent(props, context) {
-  const { name } = context
-  return <div>{name || 'not set'}</div>
-}
-```
-
-Since the above syntax is [deprecated](https://reactjs.org/docs/legacy-context.html), `@cypress/react` does not support it. Instead use `createContext` and `Context.Provider` to surround the mounted component, just like you would do in a regular application code.
-
-```js
-mount(
-  <SimpleContext.Provider value={{ name: 'test context' }}>
-    <SimpleComponent />
-  </SimpleContext.Provider>,
-)
-```
-
-Instead of setting a new context, mount the same component but surround it with a different context provider
-
-```js
-const cmp = <SimpleComponent id="0x123" />
-mount(
-  <SimpleContext.Provider value={{ name: 'first context' }}>
-    {cmp}
-  </SimpleContext.Provider>,
-)
-
-// same component, different provider
-mount(
-  <SimpleContext.Provider value={{ name: 'second context' }}>
-    {cmp}
-  </SimpleContext.Provider>,
-)
-```
-
-See [context-spec.js](context-spec.js) for more examples.
diff --git a/npm/react/cypress/component/basic/enzyme/context.cy.jsx b/npm/react/cypress/component/basic/enzyme/context.cy.jsx
deleted file mode 100644
index 87e660cab7af..000000000000
--- a/npm/react/cypress/component/basic/enzyme/context.cy.jsx
+++ /dev/null
@@ -1,53 +0,0 @@
-/// <reference types="cypress" />
-import React from 'react'
-import { mount } from '@cypress/react'
-import { SimpleContext } from './simple-context'
-import { SimpleComponent } from './simple-component.jsx'
-
-// testing components that use Context React API
-// https://reactjs.org/docs/context.html
-describe('Enzyme', () => {
-  context('setContext', () => {
-    it('does not provide the context', () => {
-      mount(<SimpleComponent />)
-      cy.contains('context not set').should('be.visible')
-    })
-
-    it('provides the context', () => {
-      // surround the component with the real provider but
-      // set the value prop to whatever the test requires
-      mount(
-        <SimpleContext.Provider value={{ name: 'test context' }}>
-          <SimpleComponent />
-        </SimpleContext.Provider>,
-      )
-
-      cy.contains('test context').should('be.visible')
-    })
-
-    it('mounts new context', () => {
-      // instead of setting the context from the test
-      // just mount the component again with a different provider around it
-      const cmp = <SimpleComponent id="0x123" />
-
-      mount(
-        <SimpleContext.Provider value={{ name: 'first context' }}>
-          {cmp}
-        </SimpleContext.Provider>,
-      )
-
-      cy.contains('first context').should('be.visible')
-      cy.contains('.id', '0x123').should('be.visible')
-
-      // same component, different provider
-      mount(
-        <SimpleContext.Provider value={{ name: 'second context' }}>
-          {cmp}
-        </SimpleContext.Provider>,
-      )
-
-      cy.contains('second context').should('be.visible')
-      cy.contains('.id', '0x123').should('be.visible')
-    })
-  })
-})
diff --git a/npm/react/cypress/component/basic/enzyme/props.cy.jsx b/npm/react/cypress/component/basic/enzyme/props.cy.jsx
deleted file mode 100644
index 0ccb58844c06..000000000000
--- a/npm/react/cypress/component/basic/enzyme/props.cy.jsx
+++ /dev/null
@@ -1,82 +0,0 @@
-/// <reference types="cypress" />
-import React from 'react'
-import { mount } from '@cypress/react'
-
-class Foo extends React.Component {
-  constructor (props) {
-    super(props)
-
-    this.state = {
-      count: 0,
-    }
-  }
-
-  componentDidMount () {
-    console.log('componentDidMount called')
-  }
-
-  componentDidUpdate () {
-    console.log('componentDidUpdate called')
-  }
-
-  render () {
-    const { id, foo } = this.props
-
-    return (
-      <div className={id}>
-        {foo} count {this.state.count}
-      </div>
-    )
-  }
-}
-
-describe('Enzyme', () => {
-  // example test copied from
-  // https://github.com/enzymejs/enzyme/blob/master/packages/enzyme-test-suite/test/shared/methods/setProps.jsx
-
-  context('setProps', () => {
-    it('gets props from the component', () => {
-      mount(<Foo id="foo" foo="initial" />).as('Foo')
-      cy.contains('initial').should('be.visible')
-
-      cy.get('@Foo')
-      .its('component')
-      .its('props')
-      .then((props) => {
-        console.log('current props', props)
-        expect(props).to.deep.equal({
-          id: 'foo',
-          foo: 'initial',
-        })
-
-        // you can get current props of the component
-        // but not change them - they are read-only
-        expect(() => {
-          props.foo = 'change 1'
-        }).to.throw()
-      })
-    })
-
-    it('mounts component with new props', () => {
-      mount(<Foo id="foo" foo="initial" />)
-      cy.contains('initial').should('be.visible')
-
-      mount(<Foo id="foo" foo="second" />)
-      cy.contains('second').should('be.visible')
-    })
-
-    it('mounts cloned component', () => {
-      const cmp = <Foo id="foo" foo="initial" />
-
-      mount(cmp)
-      cy.contains('initial').should('be.visible')
-
-      const cloned = Cypress._.cloneDeep(cmp)
-
-      // change a property, leaving the rest unchanged
-      cloned.props.foo = 'second'
-      mount(cloned)
-      cy.contains('.foo', 'second').should('be.visible')
-    })
-  })
-})
diff --git a/npm/react/cypress/component/basic/enzyme/simple-component.jsx b/npm/react/cypress/component/basic/enzyme/simple-component.jsx
deleted file mode 100644
index 57eacb77b2f8..000000000000
--- a/npm/react/cypress/component/basic/enzyme/simple-component.jsx
+++ /dev/null
@@ -1,24 +0,0 @@
-import React from 'react'
-import { SimpleContext } from './simple-context'
-
-export class SimpleComponent extends React.Component {
-  constructor (props) {
-    super(props)
-    this.state = {
-      id: props.id || 'unknown id',
-    }
-  }
-
-  render () {
-    console.log('context %o', this.context)
-
-    return (
-      <>
-        <div>{this.context.name || 'context not set'}</div>
-        <div className="id">{this.state.id}</div>
-      </>
-    )
-  }
-}
-
-SimpleComponent.contextType = SimpleContext
diff --git a/npm/react/cypress/component/basic/enzyme/simple-context.jsx b/npm/react/cypress/component/basic/enzyme/simple-context.jsx
deleted file mode 100644
index 80fd038f2e82..000000000000
--- a/npm/react/cypress/component/basic/enzyme/simple-context.jsx
+++ /dev/null
@@ -1,4 +0,0 @@
-// https://reactjs.org/docs/context.html
-import { createContext } from 'react'
-
-export const SimpleContext = createContext({ name: '' })
diff --git a/npm/react/cypress/component/basic/enzyme/state.cy.jsx b/npm/react/cypress/component/basic/enzyme/state.cy.jsx
deleted file mode 100644
index 2f3db3157097..000000000000
--- a/npm/react/cypress/component/basic/enzyme/state.cy.jsx
+++ /dev/null
@@ -1,60 +0,0 @@
-/// <reference types="cypress" />
-import React from 'react'
-import { mount } from '@cypress/react'
-
-class Foo extends React.Component {
-  constructor (props) {
-    super(props)
-
-    this.state = {
-      count: 0,
-    }
-  }
-
-  componentDidMount () {
-    console.log('componentDidMount called')
-  }
-
-  componentDidUpdate () {
-    console.log('componentDidUpdate called')
-  }
-
-  render () {
-    const { id, foo } = this.props
-
-    return (
-      <div className={id}>
-        {foo} count {this.state.count}
-      </div>
-    )
-  }
-}
-
-describe('Enzyme', () => {
-  context('setState', () => {
-    it('sets component state', () => {
-      // get the component reference using "ref" prop
-      // and place it into the object for Cypress to "wait" for it
-      let c = {}
-
-      mount(<Foo id="foo" foo="initial" ref={(i) => (c.instance = i)} />)
-      cy.contains('initial').should('be.visible')
-
-      cy.log('**check state**')
-      cy.wrap(c)
-      .its('instance.state')
-      .should('deep.equal', { count: 0 })
-
-      cy.log('**setState**')
-      cy.wrap(c)
-      .its('instance')
-      .invoke('setState', { count: 10 })
-
-      cy.wrap(c)
-      .its('instance.state')
-      .should('deep.equal', { count: 10 })
-
-      cy.contains('initial count 10')
-    })
-  })
-})
diff --git a/npm/react/cypress/component/basic/network/1-users.jsx b/npm/react/cypress/component/basic/network/1-users.jsx
index 6f879c6f6337..feb0aafacfdb 100644
--- a/npm/react/cypress/component/basic/network/1-users.jsx
+++ b/npm/react/cypress/component/basic/network/1-users.jsx
@@ -1,34 +1,26 @@
-import React from 'react'
+import React, { useState, useEffect } from 'react'
 import axios from 'axios'
 
-export class Users extends React.Component {
-  constructor (props) {
-    super(props)
-    this.state = {
-      users: [],
-    }
-  }
+export function Users () {
+  const [users, setUsers] = useState([])
 
-  componentDidMount () {
-    axios
-    .get('https://jsonplaceholder.cypress.io/users?_limit=3')
-    .then((response) => {
-      // JSON responses are automatically parsed.
-      this.setState({
-        users: response.data,
-      })
-    })
-  }
+  const getUsers = async () => {
+    const response = await axios.get('https://jsonplaceholder.cypress.io/users?_limit=3')
 
-  render () {
-    return (
-      <div>
-        {this.state.users.map((user) => (
-          <li key={user.id}>
-            <strong>{user.id}</strong> - {user.name}
-          </li>
-        ))}
-      </div>
-    )
+    setUsers(response.data)
   }
+
+  useEffect(() => {
+    getUsers()
+  }, [])
+
+  return (
+    <div>
+      {users.map((user) => (
+        <li key={user.id}>
+          <strong>{user.id}</strong> - {user.name}
+        </li>
+      ))}
+    </div>
+  )
 }
diff --git a/npm/react/cypress/component/basic/network/2-users-fetch.jsx b/npm/react/cypress/component/basic/network/2-users-fetch.jsx
index f63f26c53254..b5d302291010 100644
--- a/npm/react/cypress/component/basic/network/2-users-fetch.jsx
+++ b/npm/react/cypress/component/basic/network/2-users-fetch.jsx
@@ -1,34 +1,26 @@
-import React from 'react'
+import React, { useState, useEffect } from 'react'
 
-export class Users extends React.Component {
-  constructor (props) {
-    super(props)
-    this.state = {
-      users: [],
-    }
-  }
+export function Users () {
+  const [users, setUsers] = useState([])
 
-  componentDidMount () {
-    fetch('https://jsonplaceholder.cypress.io/users?_limit=3')
-    .then((response) => {
-      return response.json()
-    })
-    .then((list) => {
-      this.setState({
-        users: list,
-      })
-    })
-  }
+  const getUsers = async () => {
+    const response = await fetch('https://jsonplaceholder.cypress.io/users?_limit=3')
+    const list = await response.json()
 
-  render () {
-    return (
-      <div>
-        {this.state.users.map((user) => (
-          <li key={user.id}>
-            <strong>{user.id}</strong> - {user.name}
-          </li>
-        ))}
-      </div>
-    )
+    setUsers(list)
   }
+
+  useEffect(() => {
+    getUsers()
+  }, [])
+
+  return (
+    <div>
+      {users.map((user) => (
+        <li key={user.id}>
+          <strong>{user.id}</strong> - {user.name}
+        </li>
+      ))}
+    </div>
+  )
 }
diff --git a/npm/react/cypress/component/basic/react-tutorial/game.cy.jsx b/npm/react/cypress/component/basic/react-tutorial/game.cy.jsx
index c365c60638c0..263c638db5c0 100644
--- a/npm/react/cypress/component/basic/react-tutorial/game.cy.jsx
+++ b/npm/react/cypress/component/basic/react-tutorial/game.cy.jsx
@@ -5,11 +5,11 @@ import { mount } from '@cypress/react'
 import './tic-tac-toe.css'
 
 // for now need a constructor, otherwise getting "Weak map" key
-const BoardWrap = ({ squares, onClick }) => {
+const BoardWrap = ({ squares, onPlay }) => {
   return (
     <div className="game">
       <div className="game-board">
-        <Board squares={squares} onClick={onClick} />
+        <Board squares={squares} onPlay={onPlay} />
       </div>
     </div>
   )
@@ -21,16 +21,16 @@ beforeEach(() => {
 
 it('renders empty Board', () => {
   const squares = Array(9).fill(null)
-  const onClick = cy.stub()
+  const onPlay = cy.stub()
 
-  mount(<BoardWrap squares={squares} onClick={onClick} />)
+  mount(<BoardWrap squares={squares} onPlay={onPlay} />)
   cy.get('.board-row')
   .eq(0)
   .find('.square')
   .eq(0)
   .click()
   .then(() => {
-    expect(onClick).to.have.been.calledWith(0)
+    expect(onPlay).to.have.been.called
   })
 })
 
@@ -55,7 +55,7 @@ it('renders Board with a few squares filled', () => {
 
 it('plays the game', () => {
   mount(<Game />)
-  cy.contains('.game-info', 'Next player: X').should('be.visible')
+  cy.contains('.game-board > .status', 'Next player: X').should('be.visible')
   cy.get('.board-row')
   .eq(0)
   .find('.square')
@@ -87,7 +87,7 @@ it('plays the game', () => {
   .eq(2)
   .click()
 
-  cy.contains('.game-info', 'Winner: X').should('be.visible')
+  cy.contains('.game-board > .status', 'Winner: X').should('be.visible')
   // history of moves
   cy.get('ol li')
   .should('have.length', 6)
diff --git a/npm/react/cypress/component/basic/react-tutorial/game.jsx b/npm/react/cypress/component/basic/react-tutorial/game.jsx
index 65f9f6c12b74..b7b0f2f76013 100644
--- a/npm/react/cypress/component/basic/react-tutorial/game.jsx
+++ b/npm/react/cypress/component/basic/react-tutorial/game.jsx
@@ -1,129 +1,105 @@
-// from https://codepen.io/gaearon/pen/gWWZgR
-import React from 'react'
+import React, { useState } from 'react'
 
-function Square (props) {
+function Square ({ value, onSquareClick }) {
   return (
-    <button className="square" onClick={props.onClick}>
-      {props.value}
+    <button className="square" onClick={onSquareClick}>
+      {value}
     </button>
   )
 }
 
-export class Board extends React.Component {
-  renderSquare (i) {
-    return (
-      <Square
-        value={this.props.squares[i]}
-        onClick={() => this.props.onClick(i)}
-      />
-    )
-  }
-
-  render () {
-    return (
-      <div>
-        <div className="board-row">
-          {this.renderSquare(0)}
-          {this.renderSquare(1)}
-          {this.renderSquare(2)}
-        </div>
-        <div className="board-row">
-          {this.renderSquare(3)}
-          {this.renderSquare(4)}
-          {this.renderSquare(5)}
-        </div>
-        <div className="board-row">
-          {this.renderSquare(6)}
-          {this.renderSquare(7)}
-          {this.renderSquare(8)}
-        </div>
-      </div>
-    )
-  }
-}
-
-export default class Game extends React.Component {
-  constructor (props) {
-    super(props)
-    this.state = {
-      history: [
-        {
-          squares: Array(9).fill(null),
-        },
-      ],
-      stepNumber: 0,
-      xIsNext: true,
+export function Board ({ xIsNext, squares, onPlay }) {
+  function handleClick (i) {
+    if (calculateWinner(squares) || squares[i]) {
+      return
     }
-  }
 
-  handleClick (i) {
-    const history = this.state.history.slice(0, this.state.stepNumber + 1)
-    const current = history[history.length - 1]
-    const squares = current.squares.slice()
+    const nextSquares = squares.slice()
 
-    if (calculateWinner(squares) || squares[i]) {
-      return
+    if (xIsNext) {
+      nextSquares[i] = 'X'
+    } else {
+      nextSquares[i] = 'O'
     }
 
-    squares[i] = this.state.xIsNext ? 'X' : 'O'
-    this.setState({
-      history: history.concat([
-        {
-          squares,
-        },
-      ]),
-      stepNumber: history.length,
-      xIsNext: !this.state.xIsNext,
-    })
+    onPlay(nextSquares)
   }
 
-  jumpTo (step) {
-    this.setState({
-      stepNumber: step,
-      xIsNext: step % 2 === 0,
-    })
+  const winner = calculateWinner(squares)
+  let status
+
+  if (winner) {
+    status = `Winner: ${ winner}`
+  } else {
+    status = `Next player: ${ xIsNext ? 'X' : 'O'}`
   }
 
-  render () {
-    const history = this.state.history
-    const current = history[this.state.stepNumber]
-    const winner = calculateWinner(current.squares)
+  return (
+    <>
+      <div className="status">{status}</div>
+      <div className="board-row">
+        <Square value={squares[0]} onSquareClick={() => handleClick(0)} />
+        <Square value={squares[1]} onSquareClick={() => handleClick(1)} />
+        <Square value={squares[2]} onSquareClick={() => handleClick(2)} />
+      </div>
+      <div className="board-row">
+        <Square value={squares[3]} onSquareClick={() => handleClick(3)} />
+        <Square value={squares[4]} onSquareClick={() => handleClick(4)} />
+        <Square value={squares[5]} onSquareClick={() => handleClick(5)} />
+      </div>
+      <div className="board-row">
+        <Square value={squares[6]} onSquareClick={() => handleClick(6)} />
+        <Square value={squares[7]} onSquareClick={() => handleClick(7)} />
+        <Square value={squares[8]} onSquareClick={() => handleClick(8)} />
+      </div>
+    </>
+  )
+}
+
+export default function Game () {
+  const [history, setHistory] = useState([Array(9).fill(null)])
+  const [currentMove, setCurrentMove] = useState(0)
+  const xIsNext = currentMove % 2 === 0
+  const currentSquares = history[currentMove]
+
+  function handlePlay (nextSquares) {
+    const nextHistory = [...history.slice(0, currentMove + 1), nextSquares]
 
-    const moves = history.map((step, move) => {
-      const desc = move ? `Go to move #${move}` : 'Go to game start'
+    setHistory(nextHistory)
+    setCurrentMove(nextHistory.length - 1)
+  }
 
-      return (
-        <li key={move}>
-          <button onClick={() => this.jumpTo(move)}>{desc}</button>
-        </li>
-      )
-    })
+  function jumpTo (nextMove) {
+    setCurrentMove(nextMove)
+  }
 
-    let status
+  const moves = history.map((squares, move) => {
+    let description
 
-    if (winner) {
-      status = `Winner: ${winner}`
+    if (move > 0) {
+      description = `Go to move #${ move}`
     } else {
-      status = `Next player: ${this.state.xIsNext ? 'X' : 'O'}`
+      description = 'Go to game start'
     }
 
     return (
-      <div className="game">
-        <div className="game-board">
-          <Board squares={current.squares} onClick={(i) => this.handleClick(i)} />
-        </div>
-        <div className="game-info">
-          <div>{status}</div>
-          <ol>{moves}</ol>
-        </div>
-      </div>
+      <li key={move}>
+        <button onClick={() => jumpTo(move)}>{description}</button>
+      </li>
     )
-  }
-}
+  })
 
-// ========================================
-
-// ReactDOM.render(<Game />, document.getElementById('root'))
+  return (
+    <div className="game">
+      <div className="game-board">
+        <Board xIsNext={xIsNext} squares={currentSquares} onPlay={handlePlay} />
+      </div>
+      <div className="game-info">
+        <ol>{moves}</ol>
+      </div>
+    </div>
+  )
+}
 
 export function calculateWinner (squares) {
   const lines = [
diff --git a/npm/react/cypress/component/basic/react-tutorial/shopping-list.jsx b/npm/react/cypress/component/basic/react-tutorial/shopping-list.jsx
index 5d922a6b122b..8b117f38cfeb 100644
--- a/npm/react/cypress/component/basic/react-tutorial/shopping-list.jsx
+++ b/npm/react/cypress/component/basic/react-tutorial/shopping-list.jsx
@@ -1,18 +1,16 @@
 import React from 'react'
 
-export default class ShoppingList extends React.Component {
-  render () {
-    return (
-      <div className="shopping-list">
-        <h1>Shopping List for {this.props.name}</h1>
-        <ul>
-          <li>Instagram</li>
-          <li>WhatsApp</li>
-          <li>Oculus</li>
-        </ul>
-      </div>
-    )
-  }
+export default function ShoppingList ({ name }) {
+  return (
+    <div className="shopping-list">
+      <h1>Shopping List for {name}</h1>
+      <ul>
+        <li>Instagram</li>
+        <li>WhatsApp</li>
+        <li>Oculus</li>
+      </ul>
+    </div>
+  )
 }
 
 // Example usage: <ShoppingList name="Mark" />
diff --git a/npm/react/cypress/component/basic/react-tutorial/square1.jsx b/npm/react/cypress/component/basic/react-tutorial/square1.jsx
index c2ca98ddd64b..60bde2cb49a6 100644
--- a/npm/react/cypress/component/basic/react-tutorial/square1.jsx
+++ b/npm/react/cypress/component/basic/react-tutorial/square1.jsx
@@ -1,11 +1,9 @@
 import React from 'react'
 
-export default class Square extends React.Component {
-  render () {
-    return (
-      <button className="square" onClick={() => alert('click')}>
-        {this.props.value}
-      </button>
-    )
-  }
+export default function Square ({ value }) {
+  return (
+    <button className="square" onClick={() => alert('click')}>
+      {value}
+    </button>
+  )
 }
diff --git a/npm/react/cypress/component/basic/react-tutorial/square2.jsx b/npm/react/cypress/component/basic/react-tutorial/square2.jsx
index 564fd505c3de..9869d3ef332b 100644
--- a/npm/react/cypress/component/basic/react-tutorial/square2.jsx
+++ b/npm/react/cypress/component/basic/react-tutorial/square2.jsx
@@ -1,18 +1,9 @@
 import React from 'react'
 
-export default class Square extends React.Component {
-  constructor (props) {
-    super(props)
-    this.state = {
-      value: null,
-    }
-  }
-
-  render () {
-    return (
-      <button className="square" onClick={() => alert('click')}>
-        {this.props.value}
-      </button>
-    )
-  }
+export default function Square ({ value }) {
+  return (
+    <button className="square" onClick={() => alert('click')}>
+      {value || null}
+    </button>
+  )
 }
diff --git a/npm/react/cypress/component/basic/react-tutorial/square3.jsx b/npm/react/cypress/component/basic/react-tutorial/square3.jsx
index 35bc02beee2f..1c5122962847 100644
--- a/npm/react/cypress/component/basic/react-tutorial/square3.jsx
+++ b/npm/react/cypress/component/basic/react-tutorial/square3.jsx
@@ -1,18 +1,11 @@
-import React from 'react'
+import React, { useState } from 'react'
 
-export default class Square extends React.Component {
-  constructor (props) {
-    super(props)
-    this.state = {
-      value: null,
-    }
-  }
+export default function Square () {
+  const [value, setValue] = useState(null)
 
-  render () {
-    return (
-      <button className="square" onClick={() => this.setState({ value: 'X' })}>
-        {this.state.value}
-      </button>
-    )
-  }
+  return (
+    <button className="square" onClick={() => setValue('X')}>
+      {value}
+    </button>
+  )
 }
diff --git a/npm/react/cypress/component/basic/react-tutorial/square4.jsx b/npm/react/cypress/component/basic/react-tutorial/square4.jsx
index 507259650fa1..97ee0aaed834 100644
--- a/npm/react/cypress/component/basic/react-tutorial/square4.jsx
+++ b/npm/react/cypress/component/basic/react-tutorial/square4.jsx
@@ -1,9 +1,9 @@
 import React from 'react'
 
-export default function Square (props) {
+export default function Square ({ value, onClick }) {
   return (
-    <button className="square" onClick={props.onClick}>
-      {props.value}
+    <button className="square" onClick={onClick}>
+      {value}
     </button>
   )
 }
diff --git a/npm/react/cypress/component/basic/rerender/effects.cy.jsx b/npm/react/cypress/component/basic/rerender/effects.cy.jsx
index cebe663c7e08..b170d0ad6b9c 100644
--- a/npm/react/cypress/component/basic/rerender/effects.cy.jsx
+++ b/npm/react/cypress/component/basic/rerender/effects.cy.jsx
@@ -1,7 +1,6 @@
 /// <reference types="cypress" />
 import React, { useLayoutEffect, useEffect } from 'react'
-import ReactDom from 'react-dom'
-import { mount, getContainerEl } from '@cypress/react'
+import { mount } from '@cypress/react'
 
 it('should not run unmount effect cleanup when rerendering', () => {
   const layoutEffectCleanup = cy.stub()
@@ -60,8 +59,8 @@ it('should run unmount effect cleanup when unmounting', () => {
       expect(effectCleanup).to.have.been.callCount(0)
     })
 
-    cy
-    .then(() => ReactDom.unmountComponentAtNode(getContainerEl()))
+    // mount something else to trigger an unmount event
+    cy.mount(<div>Hello </div>)
     .then(async () => {
       // does not call useEffect in react 17 unmount synchronously.
       // @see https://github.com/facebook/react/issues/20263
diff --git a/npm/react/cypress/component/basic/unmount/comp.cy.jsx b/npm/react/cypress/component/basic/unmount/comp.cy.jsx
index f12b80c56e6c..c6f53a307379 100644
--- a/npm/react/cypress/component/basic/unmount/comp.cy.jsx
+++ b/npm/react/cypress/component/basic/unmount/comp.cy.jsx
@@ -1,5 +1,5 @@
 /// <reference types="cypress" />
-import Comp from './comp.jsx'
+import { Comp } from './comp.jsx'
 import React from 'react'
 import { mount, unmount } from '@cypress/react'
 
@@ -11,7 +11,6 @@ it('calls callbacks on mount and unmount', () => {
   mount(<Comp onMount={onMount} onUnmount={onUnmount} />)
   cy.then(() => {
     expect(onMount).to.have.been.calledOnce
-    expect(onUnmount).to.have.not.been.called
   })
 
   cy.contains('Component with').should('be.visible')
diff --git a/npm/react/cypress/component/basic/unmount/comp.jsx b/npm/react/cypress/component/basic/unmount/comp.jsx
index 25122014f86f..0cdb87524b58 100644
--- a/npm/react/cypress/component/basic/unmount/comp.jsx
+++ b/npm/react/cypress/component/basic/unmount/comp.jsx
@@ -1,15 +1,9 @@
-import React, { Component } from 'react'
+import React, { useEffect } from 'react'
 
-export default class Comp extends Component {
-  componentDidMount () {
-    this.props.onMount()
-  }
+export const Comp = ({ onMount }) => {
+  useEffect(() => {
+    onMount()
+  }, [])
 
-  componentWillUnmount () {
-    this.props.onUnmount()
-  }
-
-  render () {
-    return <div>Component with mount and unmount calls</div>
-  }
+  return <div>Component with mount and unmount calls</div>
 }
diff --git a/npm/react/cypress/component/basic/unmount/unmount.cy.jsx b/npm/react/cypress/component/basic/unmount/unmount.cy.jsx
deleted file mode 100644
index e4bd608e723e..000000000000
--- a/npm/react/cypress/component/basic/unmount/unmount.cy.jsx
+++ /dev/null
@@ -1,45 +0,0 @@
-/// <reference types="cypress" />
-import React, { Component } from 'react'
-import { getContainerEl } from '@cypress/mount-utils'
-import ReactDom from 'react-dom'
-import { mount } from '@cypress/react'
-
-class Comp extends Component {
-  componentWillUnmount () {
-    // simply calls the prop
-    this.props.onUnmount()
-  }
-
-  render () {
-    return <div>My component</div>
-  }
-}
-
-describe('Comp with componentWillUnmount', () => {
-  it('calls the prop', () => {
-    mount(<Comp onUnmount={cy.stub().as('onUnmount')} />)
-    cy.contains('My component')
-
-    // after we have confirmed the component exists let's remove it
-    // unmount() command is automatically enqueued
-    cy.then(() => ReactDom.unmountComponentAtNode(getContainerEl()))
-
-    // the component is gone from the DOM
-    cy.contains('My component').should('not.exist')
-    // the component has called the prop on unmount
-    cy.get('@onUnmount').should('have.been.calledOnce')
-  })
-
-  it('can be called using then', () => {
-    mount(<Comp onUnmount={cy.stub().as('onUnmount')} />)
-    cy.contains('My component')
-
-    // still works, should probably be removed in v5
-    cy.then(() => ReactDom.unmountComponentAtNode(getContainerEl()))
-
-    // the component is gone from the DOM
-    cy.contains('My component').should('not.exist')
-    // the component has called the prop on unmount
-    cy.get('@onUnmount').should('have.been.calledOnce')
-  })
-})
diff --git a/npm/react/cypress/component/basic/use-render/my-component.jsx b/npm/react/cypress/component/basic/use-render/my-component.jsx
index 76a66262e66a..5fd5db9c3180 100644
--- a/npm/react/cypress/component/basic/use-render/my-component.jsx
+++ b/npm/react/cypress/component/basic/use-render/my-component.jsx
@@ -1,10 +1,7 @@
 import React from 'react'
 
-class MyComponent extends React.Component {
-  state = {}
-  render () {
-    return <div>Hello</div>
-  }
+export function MyComponent () {
+  return <div>Hello</div>
 }
 
 export default MyComponent
diff --git a/npm/react/package.json b/npm/react/package.json
index a0f4d42f429f..bc72a7e8b8d0 100644
--- a/npm/react/package.json
+++ b/npm/react/package.json
@@ -17,25 +17,26 @@
   },
   "devDependencies": {
     "@cypress/mount-utils": "0.0.0-development",
-    "@types/semver": "7.5.0",
-    "@vitejs/plugin-react": "4.3.0",
-    "axios": "0.21.2",
+    "@types/semver": "7.5.8",
+    "@vitejs/plugin-react": "4.3.3",
+    "axios": "1.7.7",
     "cypress": "0.0.0-development",
-    "prop-types": "15.7.2",
-    "react": "17.0.2",
-    "react-dom": "17.0.2",
-    "react-router": "6.10.0",
-    "react-router-dom": "6.10.0",
+    "prop-types": "15.8.1",
+    "react": "18.3.1",
+    "react-dom": "18.3.1",
+    "react-router": "6.28.0",
+    "react-router-dom": "6.28.0",
     "semver": "^7.5.3",
     "typescript": "~5.4.5",
-    "vite": "5.2.11",
+    "vite": "5.4.10",
     "vite-plugin-require-transform": "1.0.12"
   },
   "peerDependencies": {
-    "@types/react": "^16.9.16 || ^17.0.0",
+    "@types/react": "^18",
+    "@types/react-dom": "^18",
     "cypress": "*",
-    "react": "^=16.x || ^=17.x",
-    "react-dom": "^=16.x || ^=17.x"
+    "react": "^18",
+    "react-dom": "^18"
   },
   "files": [
     "dist"
@@ -90,9 +91,6 @@
   "nx": {
     "targets": {
       "build": {
-        "dependsOn": [
-          "!@cypress/react18:build"
-        ],
         "outputs": [
           "{workspaceRoot}/cli/react",
           "{projectRoot}/dist"
diff --git a/npm/react/src/mount.ts b/npm/react/src/mount.ts
index d4cb0fa21c93..f1904fac7663 100644
--- a/npm/react/src/mount.ts
+++ b/npm/react/src/mount.ts
@@ -1,23 +1,23 @@
-import { getContainerEl } from '@cypress/mount-utils'
 import React from 'react'
-import ReactDOM from 'react-dom'
-import major from 'semver/functions/major'
+import ReactDOM from 'react-dom/client'
+import { getContainerEl } from '@cypress/mount-utils'
 import {
   makeMountFn,
   makeUnmountFn,
-} from './createMount'
+} from './index'
 import type {
   MountOptions,
   InternalMountOptions,
-} from './types'
+  UnmountArgs,
+} from './index'
 
-let lastReactDom: typeof ReactDOM
+let root: ReactDOM.Root | null
 
 const cleanup = () => {
-  if (lastReactDom) {
-    const root = getContainerEl()
+  if (root) {
+    root.unmount()
 
-    lastReactDom.unmountComponentAtNode(root)
+    root = null
 
     return true
   }
@@ -27,10 +27,10 @@ const cleanup = () => {
 
 /**
  * Mounts a React component into the DOM.
- * @param jsx {React.ReactNode} The React component to mount.
- * @param options {MountOptions} [options={}] options to pass to the mount function.
- * @param rerenderKey {string} [rerenderKey] A key to use to force a rerender.
- * @see {@link https://on.cypress.io/mounting-react} for more details.
+ * @param {import('react').JSX.Element} jsx The React component to mount.
+ * @param {MountOptions} options Options to pass to the mount function.
+ * @param {string} rerenderKey A key to use to force a rerender.
+ *
  * @example
  * import { mount } from '@cypress/react'
  * import { Stepper } from './Stepper'
@@ -40,24 +40,24 @@ const cleanup = () => {
  *   cy.get('[data-cy=increment]').click()
  *   cy.get('[data-cy=counter]').should('have.text', '1')
  * }
+ *
+ * @see {@link https://on.cypress.io/mounting-react} for more details.
+ *
+ * @returns {Cypress.Chainable<MountReturn>} The mounted component.
  */
 export function mount (jsx: React.ReactNode, options: MountOptions = {}, rerenderKey?: string) {
-  if (major(React.version) === 18) {
-    const message = '[cypress/react]: You are using `cypress/react`, which is designed for React <= 17. Consider changing to `cypress/react18`, which is designed for React 18.'
-
-    console.error(message)
-    Cypress.log({ name: 'warning', message })
-  }
-
   // Remove last mounted component if cy.mount is called more than once in a test
+  // React by default removes the last component when calling render, but we should remove the root
+  // to wipe away any state
   cleanup()
-
   const internalOptions: InternalMountOptions = {
     reactDom: ReactDOM,
-    render: (reactComponent: ReturnType<typeof React.createElement>, el: HTMLElement, reactDomToUse: typeof ReactDOM) => {
-      lastReactDom = (reactDomToUse || ReactDOM)
+    render: (reactComponent: ReturnType<typeof React.createElement>, el: HTMLElement) => {
+      if (!root) {
+        root = ReactDOM.createRoot(el)
+      }
 
-      return lastReactDom.render(reactComponent, el)
+      return root.render(reactComponent)
     },
     unmount: internalUnmount,
     cleanup,
@@ -66,20 +66,14 @@ export function mount (jsx: React.ReactNode, options: MountOptions = {}, rerende
   return makeMountFn('mount', jsx, { ReactDom: ReactDOM, ...options }, rerenderKey, internalOptions)
 }
 
-/**
- * Unmounts the component from the DOM.
- * @internal
- * @param options - Options for unmounting.
- */
 function internalUnmount (options = { log: true }) {
   return makeUnmountFn(options)
 }
-
 /**
  * Removed as of Cypress 11.0.0.
  * @see https://on.cypress.io/migration-11-0-0-component-testing-updates
  */
-export function unmount (options = { log: true }) {
+export function unmount (options: UnmountArgs = { log: true }) {
   // @ts-expect-error - undocumented API
   Cypress.utils.throwErrByPath('mount.unmount')
 }
diff --git a/npm/react/src/types.ts b/npm/react/src/types.ts
index b13bbcb1246f..e9da14f24548 100644
--- a/npm/react/src/types.ts
+++ b/npm/react/src/types.ts
@@ -8,7 +8,7 @@ export interface UnmountArgs {
 export type MountOptions = Partial<MountReactComponentOptions>
 
 export interface MountReactComponentOptions {
-  ReactDom: typeof import('react-dom')
+  ReactDom: typeof import('react-dom/client')
   /**
    * Log the mounting command into Cypress Command Log,
    * true by default.
@@ -22,11 +22,11 @@ export interface MountReactComponentOptions {
 }
 
 export interface InternalMountOptions {
-  reactDom: typeof import('react-dom')
+  reactDom: typeof import('react-dom/client')
   render: (
     reactComponent: ReturnType<typeof React.createElement>,
     el: HTMLElement,
-    reactDomToUse: typeof import('react-dom')
+    reactDomToUse: typeof import('react-dom/client')
   ) => void
   unmount: (options: UnmountArgs) => void
   cleanup: () => boolean
diff --git a/npm/react18/.eslintignore b/npm/react18/.eslintignore
deleted file mode 100644
index 79afe972da7d..000000000000
--- a/npm/react18/.eslintignore
+++ /dev/null
@@ -1,5 +0,0 @@
-**/dist
-**/*.d.ts
-**/package-lock.json
-**/tsconfig.json
-**/cypress/fixtures
\ No newline at end of file
diff --git a/npm/react18/.releaserc.js b/npm/react18/.releaserc.js
deleted file mode 100644
index 17d3bb871472..000000000000
--- a/npm/react18/.releaserc.js
+++ /dev/null
@@ -1,3 +0,0 @@
-module.exports = {
-  ...require('../../.releaserc'),
-}
diff --git a/npm/react18/CHANGELOG.md b/npm/react18/CHANGELOG.md
deleted file mode 100644
index 8afdf6422cc5..000000000000
--- a/npm/react18/CHANGELOG.md
+++ /dev/null
@@ -1,47 +0,0 @@
-# [@cypress/react18-v2.0.1](https://github.com/cypress-io/cypress/compare/@cypress/react18-v2.0.0...@cypress/react18-v2.0.1) (2024-06-07)
-
-
-### Bug Fixes
-
-* update cypress to Typescript 5 ([#29568](https://github.com/cypress-io/cypress/issues/29568)) ([f3b6766](https://github.com/cypress-io/cypress/commit/f3b67666a5db0438594339c379cf27e1fd1e4abc))
-
-# [@cypress/react18-v2.0.0](https://github.com/cypress-io/cypress/compare/@cypress/react18-v1.1.1...@cypress/react18-v2.0.0) (2022-11-07)
-
-
-### Bug Fixes
-
-* remove last mounted component upon subsequent mount calls ([#24470](https://github.com/cypress-io/cypress/issues/24470)) ([f39eb1c](https://github.com/cypress-io/cypress/commit/f39eb1c19e0923bda7ae263168fc6448da942d54))
-* remove some CT functions and props ([#24419](https://github.com/cypress-io/cypress/issues/24419)) ([294985f](https://github.com/cypress-io/cypress/commit/294985f8b3e0fa00ed66d25f88c8814603766074))
-
-
-### BREAKING CHANGES
-
-* remove last mounted component upon subsequent mount calls of mount
-
-# [@cypress/react18-v1.1.1](https://github.com/cypress-io/cypress/compare/@cypress/react18-v1.1.0...@cypress/react18-v1.1.1) (2022-10-13)
-
-
-### Bug Fixes
-
-* cypress/react18 rerender ([#23360](https://github.com/cypress-io/cypress/issues/23360)) ([8b8f20e](https://github.com/cypress-io/cypress/commit/8b8f20eec77d4c0a704aee7f7077dc92dbafb93f))
-
-# [@cypress/react18-v1.1.0](https://github.com/cypress-io/cypress/compare/@cypress/react18-v1.0.1...@cypress/react18-v1.1.0) (2022-08-30)
-
-
-### Features
-
-* adding svelte component testing support ([#23553](https://github.com/cypress-io/cypress/issues/23553)) ([f6eaad4](https://github.com/cypress-io/cypress/commit/f6eaad40e1836fa9db87c60defa5ae6f390c8fd8))
-
-# [@cypress/react18-v1.0.1](https://github.com/cypress-io/cypress/compare/@cypress/react18-v1.0.0...@cypress/react18-v1.0.1) (2022-08-15)
-
-
-### Bug Fixes
-
-* **react18:** unmount component with react18 API ([#23204](https://github.com/cypress-io/cypress/issues/23204)) ([eab950b](https://github.com/cypress-io/cypress/commit/eab950bec013f9caf5836e3fa58670fde25e2684))
-
-# @cypress/react18-v1.0.0 (2022-08-11)
-
-
-### Features
-
-* React 18 support ([#22876](https://github.com/cypress-io/cypress/issues/22876)) ([f0d3a48](https://github.com/cypress-io/cypress/commit/f0d3a4867907bf6e60468510daa883ccc8dcfb63))
diff --git a/npm/react18/README.md b/npm/react18/README.md
deleted file mode 100644
index 4f85d8081af8..000000000000
--- a/npm/react18/README.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# @cypress/react18
-
-Mount React 18 components in the open source [Cypress.io](https://www.cypress.io/) test runner
-
-> **Note:** This package is bundled with the `cypress` package and should not need to be installed separately. See the [React Component Testing Docs](https://docs.cypress.io/guides/component-testing/react/overview) for mounting React components. Installing and importing `mount` from `@cypress/react18` should only be done for advanced use-cases.
-
-## [Changelog](./CHANGELOG.md)
diff --git a/npm/react18/package.json b/npm/react18/package.json
deleted file mode 100644
index 5104e75eb943..000000000000
--- a/npm/react18/package.json
+++ /dev/null
@@ -1,71 +0,0 @@
-{
-  "name": "@cypress/react18",
-  "version": "0.0.0-development",
-  "description": "Test React components using Cypress",
-  "main": "dist/cypress-react.cjs.js",
-  "scripts": {
-    "build": "rimraf dist && rollup -c rollup.config.mjs",
-    "postbuild": "node ../../scripts/sync-exported-npm-with-cli.js",
-    "check-ts": "tsc --noEmit",
-    "lint": "eslint --ext .js,.jsx,.ts,.tsx,.json, .",
-    "watch": "yarn build --watch --watch.exclude ./dist/**/*"
-  },
-  "devDependencies": {
-    "@cypress/mount-utils": "0.0.0-development",
-    "@cypress/react": "0.0.0-development",
-    "@rollup/plugin-commonjs": "^17.1.0",
-    "@rollup/plugin-node-resolve": "^11.1.1",
-    "@types/react": "17.0.83",
-    "@types/react-dom": "17.0.25",
-    "cypress": "0.0.0-development",
-    "react": "^17.0.2",
-    "react-dom": "^17.0.2",
-    "rollup": "3.7.3",
-    "rollup-plugin-typescript2": "^0.29.0",
-    "typescript": "~5.4.5"
-  },
-  "peerDependencies": {
-    "@types/react": "^18",
-    "@types/react-dom": "^18",
-    "cypress": "*",
-    "react": "^18",
-    "react-dom": "^18"
-  },
-  "files": [
-    "dist"
-  ],
-  "types": "dist/index.d.ts",
-  "license": "MIT",
-  "repository": {
-    "type": "git",
-    "url": "https://github.com/cypress-io/cypress.git"
-  },
-  "homepage": "https://github.com/cypress-io/cypress/blob/develop/npm/react18/#readme",
-  "bugs": "https://github.com/cypress-io/cypress/issues/new?assignees=&labels=npm%3A%20%40cypress%2Freact18&template=1-bug-report.md&title=",
-  "keywords": [
-    "react",
-    "cypress",
-    "cypress-io",
-    "test",
-    "testing"
-  ],
-  "module": "dist/cypress-react.esm-bundler.js",
-  "peerDependenciesMeta": {
-    "@types/react": {
-      "optional": true
-    }
-  },
-  "publishConfig": {
-    "access": "public"
-  },
-  "nx": {
-    "targets": {
-      "build": {
-        "outputs": [
-          "{workspaceRoot}/cli/react18",
-          "{projectRoot}/dist"
-        ]
-      }
-    }
-  }
-}
diff --git a/npm/react18/rollup.config.mjs b/npm/react18/rollup.config.mjs
deleted file mode 100644
index db047e2bbd48..000000000000
--- a/npm/react18/rollup.config.mjs
+++ /dev/null
@@ -1,3 +0,0 @@
-import rollupConfig from '@cypress/react/rollup.config.mjs'
-
-export default rollupConfig
diff --git a/npm/react18/src/index.ts b/npm/react18/src/index.ts
deleted file mode 100644
index 9ab7390dfc87..000000000000
--- a/npm/react18/src/index.ts
+++ /dev/null
@@ -1,92 +0,0 @@
-import React from 'react'
-import ReactDOM from 'react-dom/client'
-import { getContainerEl } from '@cypress/mount-utils'
-import {
-  makeMountFn,
-  makeUnmountFn,
-} from '@cypress/react'
-import type {
-  MountOptions,
-  MountReturn,
-  InternalMountOptions,
-  UnmountArgs,
-} from '@cypress/react'
-
-let root: ReactDOM.Root | null
-
-const cleanup = () => {
-  if (root) {
-    root.unmount()
-
-    root = null
-
-    return true
-  }
-
-  return false
-}
-
-/**
- * Mounts a React component into the DOM.
- * @param {import('react').JSX.Element} jsx The React component to mount.
- * @param {MountOptions} options Options to pass to the mount function.
- * @param {string} rerenderKey A key to use to force a rerender.
- *
- * @example
- * import { mount } from '@cypress/react'
- * import { Stepper } from './Stepper'
- *
- * it('mounts', () => {
- *   mount(<StepperComponent />)
- *   cy.get('[data-cy=increment]').click()
- *   cy.get('[data-cy=counter]').should('have.text', '1')
- * }
- *
- * @see {@link https://on.cypress.io/mounting-react} for more details.
- *
- * @returns {Cypress.Chainable<MountReturn>} The mounted component.
- */
-export function mount (jsx: React.ReactNode, options: MountOptions = {}, rerenderKey?: string) {
-  // Remove last mounted component if cy.mount is called more than once in a test
-  // React by default removes the last component when calling render, but we should remove the root
-  // to wipe away any state
-  cleanup()
-  const internalOptions: InternalMountOptions = {
-    // @ts-expect-error
-    reactDom: ReactDOM,
-    render: (reactComponent: ReturnType<typeof React.createElement>, el: HTMLElement) => {
-      if (!root) {
-        root = ReactDOM.createRoot(el)
-      }
-
-      return root.render(reactComponent)
-    },
-    unmount: internalUnmount,
-    cleanup,
-  }
-
-  // @ts-expect-error
-  return makeMountFn('mount', jsx, { ReactDom: ReactDOM, ...options }, rerenderKey, internalOptions)
-}
-
-function internalUnmount (options = { log: true }) {
-  return makeUnmountFn(options)
-}
-/**
- * Removed as of Cypress 11.0.0.
- * @see https://on.cypress.io/migration-11-0-0-component-testing-updates
- */
-export function unmount (options: UnmountArgs = { log: true }) {
-  // @ts-expect-error - undocumented API
-  Cypress.utils.throwErrByPath('mount.unmount')
-}
-
-// Re-export this to help with migrating away from `unmount`
-export {
-  getContainerEl,
-}
-
-export type {
-  MountOptions,
-  MountReturn,
-}
diff --git a/npm/react18/tsconfig.json b/npm/react18/tsconfig.json
deleted file mode 100644
index 8e6ae3e4c8a9..000000000000
--- a/npm/react18/tsconfig.json
+++ /dev/null
@@ -1,22 +0,0 @@
-{
-  "compilerOptions": {
-    "target": "es5",
-    "module": "esnext",
-    "moduleResolution": "node",
-    "lib": [
-      "es2015",
-      "dom"
-    ],
-    "rootDir": "src",
-    "outDir": "dist",
-    "declaration": true,
-    "strict": true,
-    "types": [
-      "cypress"
-    ],
-    "allowSyntheticDefaultImports": true,
-    "esModuleInterop": true,
-    "resolveJsonModule": false
-  },
-  "include": ["src/**/*.ts"]
-}
diff --git a/npm/vite-dev-server/cypress/e2e/vite-dev-server.cy.ts b/npm/vite-dev-server/cypress/e2e/vite-dev-server.cy.ts
index 7c4959580c45..fb11182beacc 100644
--- a/npm/vite-dev-server/cypress/e2e/vite-dev-server.cy.ts
+++ b/npm/vite-dev-server/cypress/e2e/vite-dev-server.cy.ts
@@ -19,7 +19,7 @@ describe('Config options', () => {
       await ctx.actions.file.writeFileInProject(
         'src/App.cy.jsx', `
         import React from 'react'
-        import { mount } from 'cypress/react18'
+        import { mount } from 'cypress/react'
 
         export const App = () => {
           return (
diff --git a/npm/vite-plugin-cypress-esm/README.md b/npm/vite-plugin-cypress-esm/README.md
index 97cb3aed2d5a..422b211f1b1b 100644
--- a/npm/vite-plugin-cypress-esm/README.md
+++ b/npm/vite-plugin-cypress-esm/README.md
@@ -10,8 +10,8 @@ Run Cypress with `DEBUG=cypress:vite-plugin-cypress-esm`. You will get logs in t
 ## Compatibility
 
 | @cypress/vite-plugin-cypress-esm | cypress |
-| ------------------------ | ------- |
-| >= v1                    | >= v12  |
+| -------------------------------- | ------- |
+| >= v1                            | >= v12  |
 
 ## Usage
 
@@ -80,6 +80,14 @@ CypressEsm({
 })
 ```
 
+If using the `@cypress/react` test harness, you may need to ignore the `react-dom/client` module by configuring as such:
+
+```ts
+CypressEsm({
+  ignoreImportList: ['**/react-dom/client']
+})
+```
+
 ## Known Issues
 
 ### Import Syntax
diff --git a/npm/vite-plugin-cypress-esm/cypress.config.ts b/npm/vite-plugin-cypress-esm/cypress.config.ts
index 3ea2aa0a48f5..88778d7d2290 100644
--- a/npm/vite-plugin-cypress-esm/cypress.config.ts
+++ b/npm/vite-plugin-cypress-esm/cypress.config.ts
@@ -13,12 +13,11 @@ export default defineConfig({
       viteConfig: () => {
         return {
           plugins: [
-            react({
-              jsxRuntime: 'classic',
-            }),
+            react(),
             CypressEsm({
               ignoreModuleList: ['**/ignoreModuleList.cy.ts', '*MyAsync*'],
-              ignoreImportList: ['**/ImmutableModuleB*'],
+              // For `cypress/react` on react 18+, we need to ignore transforming the react-dom/client library
+              ignoreImportList: ['**/ImmutableModuleB*', '**/react-dom/client'],
             }),
           ],
         }
diff --git a/npm/vite-plugin-cypress-esm/package.json b/npm/vite-plugin-cypress-esm/package.json
index d7b5f214f551..f111d493a2b7 100644
--- a/npm/vite-plugin-cypress-esm/package.json
+++ b/npm/vite-plugin-cypress-esm/package.json
@@ -19,11 +19,11 @@
   "devDependencies": {
     "@tanstack/react-query": "4.36.1",
     "@types/picomatch": "2.3.0",
-    "@vitejs/plugin-react": "4.3.0",
-    "react": "16.8.6",
-    "react-dom": "16.8.6",
-    "react-router": "6.10.0",
-    "react-router-dom": "6.10.0",
+    "@vitejs/plugin-react": "4.3.3",
+    "react": "18.3.1",
+    "react-dom": "18.3.1",
+    "react-router": "6.28.0",
+    "react-router-dom": "6.28.0",
     "vite": "5.2.11"
   },
   "files": [
diff --git a/npm/vue/package.json b/npm/vue/package.json
index 147a496893c1..b0544dde24d1 100644
--- a/npm/vue/package.json
+++ b/npm/vue/package.json
@@ -82,9 +82,6 @@
   "nx": {
     "targets": {
       "build": {
-        "dependsOn": [
-          "!@cypress/react18:build"
-        ],
         "outputs": [
           "{workspaceRoot}/cli/vue",
           "{projectRoot}/dist"
diff --git a/npm/webpack-preprocessor/package.json b/npm/webpack-preprocessor/package.json
index 61b8978b67b9..0a614f0051c1 100644
--- a/npm/webpack-preprocessor/package.json
+++ b/npm/webpack-preprocessor/package.json
@@ -70,9 +70,6 @@
   "nx": {
     "targets": {
       "build": {
-        "dependsOn": [
-          "!@cypress/react18:build"
-        ],
         "outputs": [
           "{projectRoot}/dist"
         ]
diff --git a/packages/launchpad/cypress/e2e/config-warning.cy.ts b/packages/launchpad/cypress/e2e/config-warning.cy.ts
index 6ae9a48de1e9..a006556dc3a6 100644
--- a/packages/launchpad/cypress/e2e/config-warning.cy.ts
+++ b/packages/launchpad/cypress/e2e/config-warning.cy.ts
@@ -203,8 +203,8 @@ describe('component testing dependency warnings', () => {
     cy.get('[data-cy="warning-alert"]', { timeout: 12000 }).should('exist')
     .should('contain.text', 'Warning: Component Testing Mismatched Dependencies')
     .should('contain.text', 'vite. Expected ^4.0.0 || ^5.0.0, found 3.2.11')
-    .should('contain.text', 'react. Expected ^16.0.0 || ^17.0.0 || ^18.0.0, found 15.6.2.')
-    .should('contain.text', 'react-dom. Expected ^16.0.0 || ^17.0.0 || ^18.0.0 but dependency was not found.')
+    .should('contain.text', 'react. Expected ^18.0.0, found 15.6.2.')
+    .should('contain.text', 'react-dom. Expected ^18.0.0 but dependency was not found.')
 
     cy.get('.warning-markdown').find('li').should('have.length', 3)
   })
diff --git a/packages/reporter/cypress/support/component.ts b/packages/reporter/cypress/support/component.ts
index 7ffa238e8510..4fe6c1860b90 100644
--- a/packages/reporter/cypress/support/component.ts
+++ b/packages/reporter/cypress/support/component.ts
@@ -1,4 +1,4 @@
-import { mount } from 'cypress/react18'
+import { mount } from 'cypress/react'
 import 'cypress-real-events/support'
 import { installCustomPercyCommand } from '@packages/frontend-shared/cypress/support/customPercyCommand'
 
diff --git a/packages/scaffold-config/src/dependencies.ts b/packages/scaffold-config/src/dependencies.ts
index eeaa1e96da7d..61f92f7835a0 100644
--- a/packages/scaffold-config/src/dependencies.ts
+++ b/packages/scaffold-config/src/dependencies.ts
@@ -22,7 +22,7 @@ export const WIZARD_DEPENDENCY_REACT = {
   package: 'react',
   installer: 'react',
   description: 'A JavaScript library for building user interfaces',
-  minVersion: '^16.0.0 || ^17.0.0 || ^18.0.0',
+  minVersion: '^18.0.0',
 } as const
 
 export const WIZARD_DEPENDENCY_REACT_DOM = {
@@ -31,7 +31,7 @@ export const WIZARD_DEPENDENCY_REACT_DOM = {
   package: 'react-dom',
   installer: 'react-dom',
   description: 'This package serves as the entry point to the DOM and server renderers for React',
-  minVersion: '^16.0.0 || ^17.0.0 || ^18.0.0',
+  minVersion: '^18.0.0',
 } as const
 
 export const WIZARD_DEPENDENCY_TYPESCRIPT = {
diff --git a/packages/scaffold-config/src/frameworks.ts b/packages/scaffold-config/src/frameworks.ts
index 9c909d4ace9b..cf914d1c6903 100644
--- a/packages/scaffold-config/src/frameworks.ts
+++ b/packages/scaffold-config/src/frameworks.ts
@@ -101,16 +101,6 @@ export function getBundler (bundler: WizardBundler['type']): WizardBundler {
 
 const mountModule = <T extends string>(mountModule: T) => (projectPath: string) => Promise.resolve(mountModule)
 
-const reactMountModule = async (projectPath: string) => {
-  const reactPkg = await isDependencyInstalled(dependencies.WIZARD_DEPENDENCY_REACT, projectPath)
-
-  if (!reactPkg.detectedVersion || !semver.valid(reactPkg.detectedVersion)) {
-    return 'cypress/react'
-  }
-
-  return semver.major(reactPkg.detectedVersion) === 18 ? 'cypress/react18' : 'cypress/react'
-}
-
 export const SUPPORT_STATUSES: Readonly<Cypress.ResolvedComponentFrameworkDefinition['supportStatus'][]> = ['alpha', 'beta', 'full', 'community'] as const
 
 export const CT_FRAMEWORKS: Cypress.ComponentFrameworkDefinition[] = [
@@ -130,7 +120,7 @@ export const CT_FRAMEWORKS: Cypress.ComponentFrameworkDefinition[] = [
     },
     codeGenFramework: 'react',
     glob: '*.{js,jsx,tsx}',
-    mountModule: reactMountModule,
+    mountModule: mountModule('cypress/react'),
     supportStatus: 'full',
     /**
      * Next.js uses style-loader to inject CSS and requires this element to exist in the HTML.
@@ -176,7 +166,7 @@ export const CT_FRAMEWORKS: Cypress.ComponentFrameworkDefinition[] = [
     },
     codeGenFramework: 'react',
     glob: '*.{js,jsx,tsx}',
-    mountModule: reactMountModule,
+    mountModule: mountModule('cypress/react'),
     supportStatus: 'full',
     componentIndexHtml: componentIndexHtmlGenerator(),
   },
diff --git a/packages/scaffold-config/test/unit/supportFile.spec.ts b/packages/scaffold-config/test/unit/supportFile.spec.ts
index 745d76791a3c..ac0e12d6bec1 100644
--- a/packages/scaffold-config/test/unit/supportFile.spec.ts
+++ b/packages/scaffold-config/test/unit/supportFile.spec.ts
@@ -4,11 +4,12 @@ import { expect } from 'chai'
 
 describe('supportFileComponent', () => {
   context('react', () => {
-    for (const mountModule of ['cypress/react', 'cypress/react18'] as const) {
-      it(`handles ${mountModule} and JS`, () => {
-        const actual = supportFileComponent('js', mountModule)
+    const mountModule = 'cypress/react'
 
-        expect(actual).to.eq(dedent`
+    it(`handles ${mountModule} and JS`, () => {
+      const actual = supportFileComponent('js', mountModule)
+
+      expect(actual).to.eq(dedent`
           // ***********************************************************
           // This example support/component.js is processed and
           // loaded automatically before your test files.
@@ -37,12 +38,12 @@ describe('supportFileComponent', () => {
           // Example use:
           // cy.mount(<MyComponent />)
           `)
-      })
+    })
 
-      it(`handles ${mountModule} and TS`, () => {
-        const actual = supportFileComponent('ts', mountModule)
+    it(`handles ${mountModule} and TS`, () => {
+      const actual = supportFileComponent('ts', mountModule)
 
-        expect(actual).to.eq(dedent`
+      expect(actual).to.eq(dedent`
         // ***********************************************************
         // This example support/component.ts is processed and
         // loaded automatically before your test files.
@@ -83,8 +84,7 @@ describe('supportFileComponent', () => {
         // Example use:
         // cy.mount(<MyComponent />)
       `)
-      })
-    }
+    })
   })
 
   context('vue', () => {
diff --git a/system-tests/__snapshots__/component_testing_spec.ts.js b/system-tests/__snapshots__/component_testing_spec.ts.js
index 6172ed3738f4..b0f037b039b8 100644
--- a/system-tests/__snapshots__/component_testing_spec.ts.js
+++ b/system-tests/__snapshots__/component_testing_spec.ts.js
@@ -7,16 +7,14 @@ exports['React major versions with Webpack executes all of the tests for React v
   ┌────────────────────────────────────────────────────────────────────────────────────────────────┐
   │ Cypress:    1.2.3                                                                              │
   │ Browser:    FooBrowser 88                                                                      │
-  │ Specs:      5 found (App.cy.jsx, Unmount.cy.jsx, UsingLegacyMount.cy.jsx, Rerendering.cy.jsx,  │
-  │             mount.cy.jsx)                                                                      │
-  │ Searched:   src/App.cy.jsx, src/Unmount.cy.jsx, src/UsingLegacyMount.cy.jsx, src/Rerendering.c │
-  │             y.jsx, src/mount.cy.jsx                                                            │
+  │ Specs:      4 found (App.cy.jsx, Unmount.cy.jsx, Rerendering.cy.jsx, mount.cy.jsx)             │
+  │ Searched:   src/App.cy.jsx, src/Unmount.cy.jsx, src/Rerendering.cy.jsx, src/mount.cy.jsx       │
   └────────────────────────────────────────────────────────────────────────────────────────────────┘
 
 
 ────────────────────────────────────────────────────────────────────────────────────────────────────
                                                                                                     
-  Running:  App.cy.jsx                                                                      (1 of 5)
+  Running:  App.cy.jsx                                                                      (1 of 4)
 
 
   ✓ renders hello world
@@ -42,7 +40,7 @@ exports['React major versions with Webpack executes all of the tests for React v
 
 ────────────────────────────────────────────────────────────────────────────────────────────────────
                                                                                                     
-  Running:  Unmount.cy.jsx                                                                  (2 of 5)
+  Running:  Unmount.cy.jsx                                                                  (2 of 4)
 
 
   Comp with componentWillUnmount
@@ -73,393 +71,7 @@ exports['React major versions with Webpack executes all of the tests for React v
 
 ────────────────────────────────────────────────────────────────────────────────────────────────────
                                                                                                     
-  Running:  UsingLegacyMount.cy.jsx                                                         (3 of 5)
-
-
-  using legacy mount
-    ✓ issues a warning encouraging user to update
-
-
-  1 passing
-
-
-  (Results)
-
-  ┌────────────────────────────────────────────────────────────────────────────────────────────────┐
-  │ Tests:        1                                                                                │
-  │ Passing:      1                                                                                │
-  │ Failing:      0                                                                                │
-  │ Pending:      0                                                                                │
-  │ Skipped:      0                                                                                │
-  │ Screenshots:  0                                                                                │
-  │ Video:        false                                                                            │
-  │ Duration:     X seconds                                                                        │
-  │ Spec Ran:     UsingLegacyMount.cy.jsx                                                          │
-  └────────────────────────────────────────────────────────────────────────────────────────────────┘
-
-
-────────────────────────────────────────────────────────────────────────────────────────────────────
-                                                                                                    
-  Running:  Rerendering.cy.jsx                                                              (4 of 5)
-
-
-  re-render
-    ✓ maintains component state across re-renders
-
-
-  1 passing
-
-
-  (Results)
-
-  ┌────────────────────────────────────────────────────────────────────────────────────────────────┐
-  │ Tests:        1                                                                                │
-  │ Passing:      1                                                                                │
-  │ Failing:      0                                                                                │
-  │ Pending:      0                                                                                │
-  │ Skipped:      0                                                                                │
-  │ Screenshots:  0                                                                                │
-  │ Video:        false                                                                            │
-  │ Duration:     X seconds                                                                        │
-  │ Spec Ran:     Rerendering.cy.jsx                                                               │
-  └────────────────────────────────────────────────────────────────────────────────────────────────┘
-
-
-────────────────────────────────────────────────────────────────────────────────────────────────────
-                                                                                                    
-  Running:  mount.cy.jsx                                                                    (5 of 5)
-
-
-  mount
-    ✓ does not error when rendering primitives
-    teardown
-      ✓ should mount
-      ✓ should remove previous mounted component
-
-
-  3 passing
-
-
-  (Results)
-
-  ┌────────────────────────────────────────────────────────────────────────────────────────────────┐
-  │ Tests:        3                                                                                │
-  │ Passing:      3                                                                                │
-  │ Failing:      0                                                                                │
-  │ Pending:      0                                                                                │
-  │ Skipped:      0                                                                                │
-  │ Screenshots:  0                                                                                │
-  │ Video:        false                                                                            │
-  │ Duration:     X seconds                                                                        │
-  │ Spec Ran:     mount.cy.jsx                                                                     │
-  └────────────────────────────────────────────────────────────────────────────────────────────────┘
-
-
-====================================================================================================
-
-  (Run Finished)
-
-
-       Spec                                              Tests  Passing  Failing  Pending  Skipped  
-  ┌────────────────────────────────────────────────────────────────────────────────────────────────┐
-  │ ✔  App.cy.jsx                               XX:XX        2        2        -        -        - │
-  ├────────────────────────────────────────────────────────────────────────────────────────────────┤
-  │ ✔  Unmount.cy.jsx                           XX:XX        3        3        -        -        - │
-  ├────────────────────────────────────────────────────────────────────────────────────────────────┤
-  │ ✔  UsingLegacyMount.cy.jsx                  XX:XX        1        1        -        -        - │
-  ├────────────────────────────────────────────────────────────────────────────────────────────────┤
-  │ ✔  Rerendering.cy.jsx                       XX:XX        1        1        -        -        - │
-  ├────────────────────────────────────────────────────────────────────────────────────────────────┤
-  │ ✔  mount.cy.jsx                             XX:XX        3        3        -        -        - │
-  └────────────────────────────────────────────────────────────────────────────────────────────────┘
-    ✔  All specs passed!                        XX:XX       10       10        -        -        -  
-
-
-`
-
-exports['React major versions with Webpack executes all of the tests for React v17 with Webpack 1'] = `
-
-====================================================================================================
-
-  (Run Starting)
-
-  ┌────────────────────────────────────────────────────────────────────────────────────────────────┐
-  │ Cypress:    1.2.3                                                                              │
-  │ Browser:    FooBrowser 88                                                                      │
-  │ Specs:      5 found (App.cy.jsx, Unmount.cy.jsx, UsingLegacyMount.cy.jsx, Rerendering.cy.jsx,  │
-  │             mount.cy.jsx)                                                                      │
-  │ Searched:   src/App.cy.jsx, src/Unmount.cy.jsx, src/UsingLegacyMount.cy.jsx, src/Rerendering.c │
-  │             y.jsx, src/mount.cy.jsx                                                            │
-  └────────────────────────────────────────────────────────────────────────────────────────────────┘
-
-
-────────────────────────────────────────────────────────────────────────────────────────────────────
-                                                                                                    
-  Running:  App.cy.jsx                                                                      (1 of 5)
-   50 modules
-
-
-  ✓ renders hello world
-  ✓ renders background
-
-  2 passing
-
-
-  (Results)
-
-  ┌────────────────────────────────────────────────────────────────────────────────────────────────┐
-  │ Tests:        2                                                                                │
-  │ Passing:      2                                                                                │
-  │ Failing:      0                                                                                │
-  │ Pending:      0                                                                                │
-  │ Skipped:      0                                                                                │
-  │ Screenshots:  0                                                                                │
-  │ Video:        false                                                                            │
-  │ Duration:     X seconds                                                                        │
-  │ Spec Ran:     App.cy.jsx                                                                       │
-  └────────────────────────────────────────────────────────────────────────────────────────────────┘
-
-
-────────────────────────────────────────────────────────────────────────────────────────────────────
-                                                                                                    
-  Running:  Unmount.cy.jsx                                                                  (2 of 5)
-
-
-  Comp with componentWillUnmount
-    ✓ calls the prop
-
-  mount cleanup
-    ✓ mount 1
-    ✓ mount 2
-
-
-  3 passing
-
-
-  (Results)
-
-  ┌────────────────────────────────────────────────────────────────────────────────────────────────┐
-  │ Tests:        3                                                                                │
-  │ Passing:      3                                                                                │
-  │ Failing:      0                                                                                │
-  │ Pending:      0                                                                                │
-  │ Skipped:      0                                                                                │
-  │ Screenshots:  0                                                                                │
-  │ Video:        false                                                                            │
-  │ Duration:     X seconds                                                                        │
-  │ Spec Ran:     Unmount.cy.jsx                                                                   │
-  └────────────────────────────────────────────────────────────────────────────────────────────────┘
-
-
-────────────────────────────────────────────────────────────────────────────────────────────────────
-                                                                                                    
-  Running:  UsingLegacyMount.cy.jsx                                                         (3 of 5)
-
-
-  using legacy mount
-    ✓ does not warning or log
-
-
-  1 passing
-
-
-  (Results)
-
-  ┌────────────────────────────────────────────────────────────────────────────────────────────────┐
-  │ Tests:        1                                                                                │
-  │ Passing:      1                                                                                │
-  │ Failing:      0                                                                                │
-  │ Pending:      0                                                                                │
-  │ Skipped:      0                                                                                │
-  │ Screenshots:  0                                                                                │
-  │ Video:        false                                                                            │
-  │ Duration:     X seconds                                                                        │
-  │ Spec Ran:     UsingLegacyMount.cy.jsx                                                          │
-  └────────────────────────────────────────────────────────────────────────────────────────────────┘
-
-
-────────────────────────────────────────────────────────────────────────────────────────────────────
-                                                                                                    
-  Running:  Rerendering.cy.jsx                                                              (4 of 5)
-
-
-  re-render
-    ✓ maintains component state across re-renders
-
-
-  1 passing
-
-
-  (Results)
-
-  ┌────────────────────────────────────────────────────────────────────────────────────────────────┐
-  │ Tests:        1                                                                                │
-  │ Passing:      1                                                                                │
-  │ Failing:      0                                                                                │
-  │ Pending:      0                                                                                │
-  │ Skipped:      0                                                                                │
-  │ Screenshots:  0                                                                                │
-  │ Video:        false                                                                            │
-  │ Duration:     X seconds                                                                        │
-  │ Spec Ran:     Rerendering.cy.jsx                                                               │
-  └────────────────────────────────────────────────────────────────────────────────────────────────┘
-
-
-────────────────────────────────────────────────────────────────────────────────────────────────────
-                                                                                                    
-  Running:  mount.cy.jsx                                                                    (5 of 5)
-
-
-  mount
-    ✓ does not error when rendering primitives
-    teardown
-      ✓ should mount
-      ✓ should remove previous mounted component
-
-
-  3 passing
-
-
-  (Results)
-
-  ┌────────────────────────────────────────────────────────────────────────────────────────────────┐
-  │ Tests:        3                                                                                │
-  │ Passing:      3                                                                                │
-  │ Failing:      0                                                                                │
-  │ Pending:      0                                                                                │
-  │ Skipped:      0                                                                                │
-  │ Screenshots:  0                                                                                │
-  │ Video:        false                                                                            │
-  │ Duration:     X seconds                                                                        │
-  │ Spec Ran:     mount.cy.jsx                                                                     │
-  └────────────────────────────────────────────────────────────────────────────────────────────────┘
-
-
-====================================================================================================
-
-  (Run Finished)
-
-
-       Spec                                              Tests  Passing  Failing  Pending  Skipped  
-  ┌────────────────────────────────────────────────────────────────────────────────────────────────┐
-  │ ✔  App.cy.jsx                               XX:XX        2        2        -        -        - │
-  ├────────────────────────────────────────────────────────────────────────────────────────────────┤
-  │ ✔  Unmount.cy.jsx                           XX:XX        3        3        -        -        - │
-  ├────────────────────────────────────────────────────────────────────────────────────────────────┤
-  │ ✔  UsingLegacyMount.cy.jsx                  XX:XX        1        1        -        -        - │
-  ├────────────────────────────────────────────────────────────────────────────────────────────────┤
-  │ ✔  Rerendering.cy.jsx                       XX:XX        1        1        -        -        - │
-  ├────────────────────────────────────────────────────────────────────────────────────────────────┤
-  │ ✔  mount.cy.jsx                             XX:XX        3        3        -        -        - │
-  └────────────────────────────────────────────────────────────────────────────────────────────────┘
-    ✔  All specs passed!                        XX:XX       10       10        -        -        -  
-
-
-`
-
-exports['React major versions with Vite executes all of the tests for React v17 with Vite 1'] = `
-
-====================================================================================================
-
-  (Run Starting)
-
-  ┌────────────────────────────────────────────────────────────────────────────────────────────────┐
-  │ Cypress:    1.2.3                                                                              │
-  │ Browser:    FooBrowser 88                                                                      │
-  │ Specs:      5 found (App.cy.jsx, Unmount.cy.jsx, UsingLegacyMount.cy.jsx, Rerendering.cy.jsx,  │
-  │             mount.cy.jsx)                                                                      │
-  │ Searched:   src/App.cy.jsx, src/Unmount.cy.jsx, src/UsingLegacyMount.cy.jsx, src/Rerendering.c │
-  │             y.jsx, src/mount.cy.jsx                                                            │
-  └────────────────────────────────────────────────────────────────────────────────────────────────┘
-
-
-────────────────────────────────────────────────────────────────────────────────────────────────────
-                                                                                                    
-  Running:  App.cy.jsx                                                                      (1 of 5)
-
-
-  ✓ renders hello world
-  ✓ renders background
-
-  2 passing
-
-
-  (Results)
-
-  ┌────────────────────────────────────────────────────────────────────────────────────────────────┐
-  │ Tests:        2                                                                                │
-  │ Passing:      2                                                                                │
-  │ Failing:      0                                                                                │
-  │ Pending:      0                                                                                │
-  │ Skipped:      0                                                                                │
-  │ Screenshots:  0                                                                                │
-  │ Video:        false                                                                            │
-  │ Duration:     X seconds                                                                        │
-  │ Spec Ran:     App.cy.jsx                                                                       │
-  └────────────────────────────────────────────────────────────────────────────────────────────────┘
-
-
-────────────────────────────────────────────────────────────────────────────────────────────────────
-                                                                                                    
-  Running:  Unmount.cy.jsx                                                                  (2 of 5)
-
-
-  Comp with componentWillUnmount
-    ✓ calls the prop
-
-  mount cleanup
-    ✓ mount 1
-    ✓ mount 2
-
-
-  3 passing
-
-
-  (Results)
-
-  ┌────────────────────────────────────────────────────────────────────────────────────────────────┐
-  │ Tests:        3                                                                                │
-  │ Passing:      3                                                                                │
-  │ Failing:      0                                                                                │
-  │ Pending:      0                                                                                │
-  │ Skipped:      0                                                                                │
-  │ Screenshots:  0                                                                                │
-  │ Video:        false                                                                            │
-  │ Duration:     X seconds                                                                        │
-  │ Spec Ran:     Unmount.cy.jsx                                                                   │
-  └────────────────────────────────────────────────────────────────────────────────────────────────┘
-
-
-────────────────────────────────────────────────────────────────────────────────────────────────────
-                                                                                                    
-  Running:  UsingLegacyMount.cy.jsx                                                         (3 of 5)
-
-
-  using legacy mount
-    ✓ does not warning or log
-
-
-  1 passing
-
-
-  (Results)
-
-  ┌────────────────────────────────────────────────────────────────────────────────────────────────┐
-  │ Tests:        1                                                                                │
-  │ Passing:      1                                                                                │
-  │ Failing:      0                                                                                │
-  │ Pending:      0                                                                                │
-  │ Skipped:      0                                                                                │
-  │ Screenshots:  0                                                                                │
-  │ Video:        false                                                                            │
-  │ Duration:     X seconds                                                                        │
-  │ Spec Ran:     UsingLegacyMount.cy.jsx                                                          │
-  └────────────────────────────────────────────────────────────────────────────────────────────────┘
-
-
-────────────────────────────────────────────────────────────────────────────────────────────────────
-                                                                                                    
-  Running:  Rerendering.cy.jsx                                                              (4 of 5)
+  Running:  Rerendering.cy.jsx                                                              (3 of 4)
 
 
   re-render
@@ -486,7 +98,7 @@ exports['React major versions with Vite executes all of the tests for React v17
 
 ────────────────────────────────────────────────────────────────────────────────────────────────────
                                                                                                     
-  Running:  mount.cy.jsx                                                                    (5 of 5)
+  Running:  mount.cy.jsx                                                                    (4 of 4)
 
 
   mount
@@ -525,13 +137,11 @@ exports['React major versions with Vite executes all of the tests for React v17
   ├────────────────────────────────────────────────────────────────────────────────────────────────┤
   │ ✔  Unmount.cy.jsx                           XX:XX        3        3        -        -        - │
   ├────────────────────────────────────────────────────────────────────────────────────────────────┤
-  │ ✔  UsingLegacyMount.cy.jsx                  XX:XX        1        1        -        -        - │
-  ├────────────────────────────────────────────────────────────────────────────────────────────────┤
   │ ✔  Rerendering.cy.jsx                       XX:XX        1        1        -        -        - │
   ├────────────────────────────────────────────────────────────────────────────────────────────────┤
   │ ✔  mount.cy.jsx                             XX:XX        3        3        -        -        - │
   └────────────────────────────────────────────────────────────────────────────────────────────────┘
-    ✔  All specs passed!                        XX:XX       10       10        -        -        -  
+    ✔  All specs passed!                        XX:XX        9        9        -        -        -  
 
 
 `
@@ -545,16 +155,14 @@ exports['React major versions with Vite executes all of the tests for React v18
   ┌────────────────────────────────────────────────────────────────────────────────────────────────┐
   │ Cypress:    1.2.3                                                                              │
   │ Browser:    FooBrowser 88                                                                      │
-  │ Specs:      5 found (App.cy.jsx, Unmount.cy.jsx, UsingLegacyMount.cy.jsx, Rerendering.cy.jsx,  │
-  │             mount.cy.jsx)                                                                      │
-  │ Searched:   src/App.cy.jsx, src/Unmount.cy.jsx, src/UsingLegacyMount.cy.jsx, src/Rerendering.c │
-  │             y.jsx, src/mount.cy.jsx                                                            │
+  │ Specs:      4 found (App.cy.jsx, Unmount.cy.jsx, Rerendering.cy.jsx, mount.cy.jsx)             │
+  │ Searched:   src/App.cy.jsx, src/Unmount.cy.jsx, src/Rerendering.cy.jsx, src/mount.cy.jsx       │
   └────────────────────────────────────────────────────────────────────────────────────────────────┘
 
 
 ────────────────────────────────────────────────────────────────────────────────────────────────────
                                                                                                     
-  Running:  App.cy.jsx                                                                      (1 of 5)
+  Running:  App.cy.jsx                                                                      (1 of 4)
 
 
   ✓ renders hello world
@@ -580,7 +188,7 @@ exports['React major versions with Vite executes all of the tests for React v18
 
 ────────────────────────────────────────────────────────────────────────────────────────────────────
                                                                                                     
-  Running:  Unmount.cy.jsx                                                                  (2 of 5)
+  Running:  Unmount.cy.jsx                                                                  (2 of 4)
 
 
   Comp with componentWillUnmount
@@ -611,34 +219,7 @@ exports['React major versions with Vite executes all of the tests for React v18
 
 ────────────────────────────────────────────────────────────────────────────────────────────────────
                                                                                                     
-  Running:  UsingLegacyMount.cy.jsx                                                         (3 of 5)
-
-
-  using legacy mount
-    ✓ issues a warning encouraging user to update
-
-
-  1 passing
-
-
-  (Results)
-
-  ┌────────────────────────────────────────────────────────────────────────────────────────────────┐
-  │ Tests:        1                                                                                │
-  │ Passing:      1                                                                                │
-  │ Failing:      0                                                                                │
-  │ Pending:      0                                                                                │
-  │ Skipped:      0                                                                                │
-  │ Screenshots:  0                                                                                │
-  │ Video:        false                                                                            │
-  │ Duration:     X seconds                                                                        │
-  │ Spec Ran:     UsingLegacyMount.cy.jsx                                                          │
-  └────────────────────────────────────────────────────────────────────────────────────────────────┘
-
-
-────────────────────────────────────────────────────────────────────────────────────────────────────
-                                                                                                    
-  Running:  Rerendering.cy.jsx                                                              (4 of 5)
+  Running:  Rerendering.cy.jsx                                                              (3 of 4)
 
 
   re-render
@@ -665,7 +246,7 @@ exports['React major versions with Vite executes all of the tests for React v18
 
 ────────────────────────────────────────────────────────────────────────────────────────────────────
                                                                                                     
-  Running:  mount.cy.jsx                                                                    (5 of 5)
+  Running:  mount.cy.jsx                                                                    (4 of 4)
 
 
   mount
@@ -704,13 +285,11 @@ exports['React major versions with Vite executes all of the tests for React v18
   ├────────────────────────────────────────────────────────────────────────────────────────────────┤
   │ ✔  Unmount.cy.jsx                           XX:XX        3        3        -        -        - │
   ├────────────────────────────────────────────────────────────────────────────────────────────────┤
-  │ ✔  UsingLegacyMount.cy.jsx                  XX:XX        1        1        -        -        - │
-  ├────────────────────────────────────────────────────────────────────────────────────────────────┤
   │ ✔  Rerendering.cy.jsx                       XX:XX        1        1        -        -        - │
   ├────────────────────────────────────────────────────────────────────────────────────────────────┤
   │ ✔  mount.cy.jsx                             XX:XX        3        3        -        -        - │
   └────────────────────────────────────────────────────────────────────────────────────────────────┘
-    ✔  All specs passed!                        XX:XX       10       10        -        -        -  
+    ✔  All specs passed!                        XX:XX        9        9        -        -        -  
 
 
 `
diff --git a/system-tests/project-fixtures/react/cypress/support/component.js b/system-tests/project-fixtures/react/cypress/support/component.js
index 96736d7047cb..fd025808277a 100644
--- a/system-tests/project-fixtures/react/cypress/support/component.js
+++ b/system-tests/project-fixtures/react/cypress/support/component.js
@@ -1,4 +1,4 @@
-import { mount } from 'cypress/react18'
+import { mount } from 'cypress/react'
 
 import './backgroundColor.css'
 
diff --git a/system-tests/project-fixtures/runner-specs/cypress/support/component.js b/system-tests/project-fixtures/runner-specs/cypress/support/component.js
index 70284198ed61..86674a7a022b 100644
--- a/system-tests/project-fixtures/runner-specs/cypress/support/component.js
+++ b/system-tests/project-fixtures/runner-specs/cypress/support/component.js
@@ -1,3 +1,3 @@
-import { mount } from 'cypress/react18'
+import { mount } from 'cypress/react'
 
 Cypress.Commands.add('mount', mount)
diff --git a/system-tests/projects/cypress-in-cypress/src/NewComponent.spec.jsx b/system-tests/projects/cypress-in-cypress/src/NewComponent.spec.jsx
index fe8ee97c541a..a202ae027161 100644
--- a/system-tests/projects/cypress-in-cypress/src/NewComponent.spec.jsx
+++ b/system-tests/projects/cypress-in-cypress/src/NewComponent.spec.jsx
@@ -1,5 +1,5 @@
 import React from 'react'
-import { mount } from 'cypress/react18'
+import { mount } from 'cypress/react'
 
 describe('NewComponent', () => {
   it('renders the new component', () => {
diff --git a/system-tests/projects/cypress-in-cypress/src/TestComponent.spec.jsx b/system-tests/projects/cypress-in-cypress/src/TestComponent.spec.jsx
index 214c74d911cf..0324c25cf485 100644
--- a/system-tests/projects/cypress-in-cypress/src/TestComponent.spec.jsx
+++ b/system-tests/projects/cypress-in-cypress/src/TestComponent.spec.jsx
@@ -1,5 +1,5 @@
 import React from 'react'
-import { mount } from 'cypress/react18'
+import { mount } from 'cypress/react'
 
 describe('TestComponent', () => {
   it('renders the test component', () => {
diff --git a/system-tests/projects/experimental-JIT/vite/cypress/support/component.js b/system-tests/projects/experimental-JIT/vite/cypress/support/component.js
index 70284198ed61..86674a7a022b 100644
--- a/system-tests/projects/experimental-JIT/vite/cypress/support/component.js
+++ b/system-tests/projects/experimental-JIT/vite/cypress/support/component.js
@@ -1,3 +1,3 @@
-import { mount } from 'cypress/react18'
+import { mount } from 'cypress/react'
 
 Cypress.Commands.add('mount', mount)
diff --git a/system-tests/projects/experimental-JIT/webpack/cypress/support/component.js b/system-tests/projects/experimental-JIT/webpack/cypress/support/component.js
index 70284198ed61..86674a7a022b 100644
--- a/system-tests/projects/experimental-JIT/webpack/cypress/support/component.js
+++ b/system-tests/projects/experimental-JIT/webpack/cypress/support/component.js
@@ -1,3 +1,3 @@
-import { mount } from 'cypress/react18'
+import { mount } from 'cypress/react'
 
 Cypress.Commands.add('mount', mount)
diff --git a/system-tests/projects/next-14-tsconfig-tailwind/cypress/support/component.ts b/system-tests/projects/next-14-tsconfig-tailwind/cypress/support/component.ts
index 44bd3a01d77e..81d0e5e698cb 100644
--- a/system-tests/projects/next-14-tsconfig-tailwind/cypress/support/component.ts
+++ b/system-tests/projects/next-14-tsconfig-tailwind/cypress/support/component.ts
@@ -1,6 +1,6 @@
 import 'tailwindcss/tailwind.css'
 
-import { mount } from 'cypress/react18'
+import { mount } from 'cypress/react'
 
 declare global {
   namespace Cypress {
diff --git a/system-tests/projects/nextjs-configured/components/button.cy.jsx b/system-tests/projects/nextjs-configured/components/button.cy.jsx
index 02e1ca0a1a77..7078df6ba3b8 100644
--- a/system-tests/projects/nextjs-configured/components/button.cy.jsx
+++ b/system-tests/projects/nextjs-configured/components/button.cy.jsx
@@ -1,5 +1,5 @@
 import React from 'react'
-import { mount } from 'cypress/react18'
+import { mount } from 'cypress/react'
 import { Button } from './button'
 
 it('works', () => {
diff --git a/system-tests/projects/nextjs-unconfigured/components/button.cy.jsx b/system-tests/projects/nextjs-unconfigured/components/button.cy.jsx
index 02e1ca0a1a77..7078df6ba3b8 100644
--- a/system-tests/projects/nextjs-unconfigured/components/button.cy.jsx
+++ b/system-tests/projects/nextjs-unconfigured/components/button.cy.jsx
@@ -1,5 +1,5 @@
 import React from 'react'
-import { mount } from 'cypress/react18'
+import { mount } from 'cypress/react'
 import { Button } from './button'
 
 it('works', () => {
diff --git a/system-tests/projects/no-specs/cypress/support/component.js b/system-tests/projects/no-specs/cypress/support/component.js
index b70bd8c84f3a..be20eaa89ea2 100644
--- a/system-tests/projects/no-specs/cypress/support/component.js
+++ b/system-tests/projects/no-specs/cypress/support/component.js
@@ -19,7 +19,7 @@ import './commands'
 // Alternatively you can use CommonJS syntax:
 // require('./commands')
 
-import { mount } from 'cypress/react18'
+import { mount } from 'cypress/react'
 
 Cypress.Commands.add('mount', mount)
 
diff --git a/system-tests/projects/protocol/cypress/support/component.ts b/system-tests/projects/protocol/cypress/support/component.ts
index 52b74e5f5862..b3c30eabe612 100644
--- a/system-tests/projects/protocol/cypress/support/component.ts
+++ b/system-tests/projects/protocol/cypress/support/component.ts
@@ -1,4 +1,4 @@
-import { mount } from 'cypress/react18'
+import { mount } from 'cypress/react'
 
 // Augment the Cypress namespace to include type definitions for
 // your custom command.
diff --git a/system-tests/projects/react-vite-ts-configured/src/App.cy.tsx b/system-tests/projects/react-vite-ts-configured/src/App.cy.tsx
index 08fe40cbe427..4b2373579092 100644
--- a/system-tests/projects/react-vite-ts-configured/src/App.cy.tsx
+++ b/system-tests/projects/react-vite-ts-configured/src/App.cy.tsx
@@ -1,5 +1,5 @@
 import React from 'react'
-import { mount } from 'cypress/react18'
+import { mount } from 'cypress/react'
 import App from './App.tsx'
 
 it('works', () => {
diff --git a/system-tests/projects/react18/cypress/support/component.js b/system-tests/projects/react18/cypress/support/component.js
index 96736d7047cb..fd025808277a 100644
--- a/system-tests/projects/react18/cypress/support/component.js
+++ b/system-tests/projects/react18/cypress/support/component.js
@@ -1,4 +1,4 @@
-import { mount } from 'cypress/react18'
+import { mount } from 'cypress/react'
 
 import './backgroundColor.css'
 
diff --git a/system-tests/projects/react18/src/UsingLegacyMount.cy.jsx b/system-tests/projects/react18/src/UsingLegacyMount.cy.jsx
deleted file mode 100644
index 3bb5e5147cbc..000000000000
--- a/system-tests/projects/react18/src/UsingLegacyMount.cy.jsx
+++ /dev/null
@@ -1,23 +0,0 @@
-import React from 'react'
-import { mount } from 'cypress/react'
-
-function App () {
-  return <h1>Hello world</h1>
-}
-
-describe('using legacy mount', () => {
-  it('issues a warning encouraging user to update', () => {
-    // dont log else we create an endless loop!
-    const log = cy.spy(Cypress, 'log').log(false)
-    const err = cy.spy(console, 'error')
-
-    mount(<App />).get('h1').contains('Hello world')
-    .then(() => {
-      const msg = '[cypress/react]: You are using `cypress/react`, which is designed for React <= 17. Consider changing to `cypress/react18`, which is designed for React 18.'
-      const warning = log.getCalls().find((call) => call.args[0].name === 'warning')
-
-      expect(warning.lastArg.message).to.eq(msg)
-      expect(err).to.have.been.calledWith(msg)
-    })
-  })
-})
diff --git a/system-tests/projects/tailwind-vite/src/App.cy.jsx b/system-tests/projects/tailwind-vite/src/App.cy.jsx
index 9bfbd96f48a5..c37ea8ba9b9f 100644
--- a/system-tests/projects/tailwind-vite/src/App.cy.jsx
+++ b/system-tests/projects/tailwind-vite/src/App.cy.jsx
@@ -1,5 +1,5 @@
 import React from 'react'
-import { mount } from 'cypress/react18'
+import { mount } from 'cypress/react'
 
 export const App = () => {
   return (
diff --git a/system-tests/projects/vite-simple/cypress/support/component.js b/system-tests/projects/vite-simple/cypress/support/component.js
index 70284198ed61..86674a7a022b 100644
--- a/system-tests/projects/vite-simple/cypress/support/component.js
+++ b/system-tests/projects/vite-simple/cypress/support/component.js
@@ -1,3 +1,3 @@
-import { mount } from 'cypress/react18'
+import { mount } from 'cypress/react'
 
 Cypress.Commands.add('mount', mount)
diff --git a/system-tests/projects/webpack-dev-server-relative/src/relative-url.cy.jsx b/system-tests/projects/webpack-dev-server-relative/src/relative-url.cy.jsx
index b47c72bea025..1429f4367dd4 100644
--- a/system-tests/projects/webpack-dev-server-relative/src/relative-url.cy.jsx
+++ b/system-tests/projects/webpack-dev-server-relative/src/relative-url.cy.jsx
@@ -1,5 +1,5 @@
 import React from 'react'
-import { mount } from 'cypress/react18'
+import { mount } from 'cypress/react'
 
 describe('webpack-dev-server', () => {
   it('image with relative path should load', () => {
diff --git a/system-tests/projects/webpack5_wds4-react/src/App.cy.jsx b/system-tests/projects/webpack5_wds4-react/src/App.cy.jsx
index df11cbb62b75..523c026f0797 100644
--- a/system-tests/projects/webpack5_wds4-react/src/App.cy.jsx
+++ b/system-tests/projects/webpack5_wds4-react/src/App.cy.jsx
@@ -1,6 +1,6 @@
 import React from 'react'
 import { App } from './App'
-import { mount } from 'cypress/react18'
+import { mount } from 'cypress/react'
 
 it('renders hello world', () => {
   mount(<App />)
diff --git a/system-tests/projects/webpack5_wds5-react/src/App.cy.jsx b/system-tests/projects/webpack5_wds5-react/src/App.cy.jsx
index df11cbb62b75..523c026f0797 100644
--- a/system-tests/projects/webpack5_wds5-react/src/App.cy.jsx
+++ b/system-tests/projects/webpack5_wds5-react/src/App.cy.jsx
@@ -1,6 +1,6 @@
 import React from 'react'
 import { App } from './App'
-import { mount } from 'cypress/react18'
+import { mount } from 'cypress/react'
 
 it('renders hello world', () => {
   mount(<App />)
diff --git a/system-tests/test/component_testing_spec.ts b/system-tests/test/component_testing_spec.ts
index 82bb5a1e7a0d..9644f3d94968 100644
--- a/system-tests/test/component_testing_spec.ts
+++ b/system-tests/test/component_testing_spec.ts
@@ -47,7 +47,7 @@ describe(`React major versions with Vite`, function () {
       return systemTests.exec(this, {
         project: `react${majorVersion}`,
         configFile: 'cypress-vite-default.config.ts',
-        spec: 'src/App.cy.jsx,src/Unmount.cy.jsx,src/UsingLegacyMount.cy.jsx,src/Rerendering.cy.jsx,src/mount.cy.jsx',
+        spec: 'src/App.cy.jsx,src/Unmount.cy.jsx,src/Rerendering.cy.jsx,src/mount.cy.jsx',
         testingType: 'component',
         browser: 'chrome',
         snapshot: true,
@@ -65,7 +65,7 @@ describe(`React major versions with Webpack`, function () {
       return systemTests.exec(this, {
         project: `react${majorVersion}`,
         configFile: 'cypress-webpack.config.ts',
-        spec: 'src/App.cy.jsx,src/Unmount.cy.jsx,src/UsingLegacyMount.cy.jsx,src/Rerendering.cy.jsx,src/mount.cy.jsx',
+        spec: 'src/App.cy.jsx,src/Unmount.cy.jsx,src/Rerendering.cy.jsx,src/mount.cy.jsx',
         testingType: 'component',
         browser: 'chrome',
         snapshot: true,
diff --git a/yarn.lock b/yarn.lock
index 4c8695e5279a..10224f4b4ffc 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1562,10 +1562,10 @@
   dependencies:
     "@babel/types" "^7.24.7"
 
-"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.20.2", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.24.6", "@babel/helper-plugin-utils@^7.24.7", "@babel/helper-plugin-utils@^7.24.8", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3":
-  version "7.24.8"
-  resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz#94ee67e8ec0e5d44ea7baeb51e571bd26af07878"
-  integrity sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==
+"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.20.2", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.24.7", "@babel/helper-plugin-utils@^7.24.8", "@babel/helper-plugin-utils@^7.25.9", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3":
+  version "7.25.9"
+  resolved "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.9.tgz#9cbdd63a9443a2c92a725cca7ebca12cc8dd9f46"
+  integrity sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==
 
 "@babel/helper-remap-async-to-generator@^7.24.7", "@babel/helper-remap-async-to-generator@^7.25.0":
   version "7.25.0"
@@ -2229,19 +2229,19 @@
   dependencies:
     "@babel/plugin-transform-react-jsx" "^7.24.7"
 
-"@babel/plugin-transform-react-jsx-self@^7.24.5":
-  version "7.24.6"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.24.6.tgz#4fa4870d594d6840d724d2006d0f98b19be6f502"
-  integrity sha512-FfZfHXtQ5jYPQsCRyLpOv2GeLIIJhs8aydpNh39vRDjhD411XcfWDni5i7OjP/Rs8GAtTn7sWFFELJSHqkIxYg==
+"@babel/plugin-transform-react-jsx-self@^7.24.7":
+  version "7.25.9"
+  resolved "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.25.9.tgz#c0b6cae9c1b73967f7f9eb2fca9536ba2fad2858"
+  integrity sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.24.6"
+    "@babel/helper-plugin-utils" "^7.25.9"
 
-"@babel/plugin-transform-react-jsx-source@^7.24.1":
-  version "7.24.6"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.24.6.tgz#4e1503f24ca5fccb1fc7f20c57426899d5ce5c1f"
-  integrity sha512-BQTBCXmFRreU3oTUXcGKuPOfXAGb1liNY4AvvFKsOBAJ89RKcTsIrSsnMYkj59fNa66OFKnSa4AJZfy5Y4B9WA==
+"@babel/plugin-transform-react-jsx-source@^7.24.7":
+  version "7.25.9"
+  resolved "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.25.9.tgz#4c6b8daa520b5f155b5fb55547d7c9fa91417503"
+  integrity sha512-+iqjT8xmXhhYv4/uiYd8FNQsraMFZIfxVSqxxVSZP0WbbSAWvBXAul0m/zu+7Vv4O/3WtApy9pmaTMiumEZgfg==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.24.6"
+    "@babel/helper-plugin-utils" "^7.25.9"
 
 "@babel/plugin-transform-react-jsx@^7.0.0", "@babel/plugin-transform-react-jsx@^7.24.7":
   version "7.25.2"
@@ -6231,10 +6231,10 @@
     tslib "^2.0.0"
     warning "^4.0.3"
 
-"@remix-run/router@1.5.0":
-  version "1.5.0"
-  resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.5.0.tgz#57618e57942a5f0131374a9fdb0167e25a117fdc"
-  integrity sha512-bkUDCp8o1MvFO+qxkODcbhSqRa6P2GXgrGZVpt0dCXNW2HCSCqYI0ZoAqEOSAjRWmmlKcYgFvN4B4S+zo/f8kg==
+"@remix-run/router@1.21.0":
+  version "1.21.0"
+  resolved "https://registry.npmjs.org/@remix-run/router/-/router-1.21.0.tgz#c65ae4262bdcfe415dbd4f64ec87676e4a56e2b5"
+  integrity sha512-xfSkCAchbdG5PnbrKqFWwia4Bi61nH+wm8wLEqfHDyp7Y3dZzgqS2itV8i4gAq9pC2HsTpwyBC6Ds8VHZ96JlA==
 
 "@rollup/plugin-commonjs@^17.1.0":
   version "17.1.0"
@@ -8195,13 +8195,6 @@
   resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.3.tgz#7ee330ba7caafb98090bece86a5ee44115904c2c"
   integrity sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==
 
-"@types/react-dom@17.0.25":
-  version "17.0.25"
-  resolved "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.25.tgz#e0e5b3571e1069625b3a3da2b279379aa33a0cb5"
-  integrity sha512-urx7A7UxkZQmThYA4So0NelOVjx3V4rNFVJwp0WZlbIK5eM4rNJDiN3R/E9ix0MBh6kAEojk/9YL+Te6D9zHNA==
-  dependencies:
-    "@types/react" "^17"
-
 "@types/react-dom@18.3.1":
   version "18.3.1"
   resolved "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.1.tgz#1e4654c08a9cdcfb6594c780ac59b55aad42fe07"
@@ -8217,15 +8210,6 @@
     "@types/prop-types" "*"
     csstype "^3.0.2"
 
-"@types/react@17.0.83", "@types/react@^17":
-  version "17.0.83"
-  resolved "https://registry.npmjs.org/@types/react/-/react-17.0.83.tgz#b477c56387b74279281149dcf5ba2a1e2216d131"
-  integrity sha512-l0m4ArKJvmFtR4e8UmKrj1pB4tUgOhJITf+mADyF/p69Ts1YAR/E+G9XEM0mHXKVRa1dQNHseyyDNzeuAXfXQw==
-  dependencies:
-    "@types/prop-types" "*"
-    "@types/scheduler" "^0.16"
-    csstype "^3.0.2"
-
 "@types/react@^16":
   version "16.14.62"
   resolved "https://registry.npmjs.org/@types/react/-/react-16.14.62.tgz#449e4e81caaf132d0c2c390644e577702db1dd9e"
@@ -8295,12 +8279,7 @@
   resolved "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz#ce5ace04cfeabe7ef87c0091e50752e36707deff"
   integrity sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==
 
-"@types/semver@7.5.0":
-  version "7.5.0"
-  resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.0.tgz#591c1ce3a702c45ee15f47a42ade72c2fd78978a"
-  integrity sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==
-
-"@types/semver@^7.5.0":
+"@types/semver@7.5.8", "@types/semver@^7.5.0":
   version "7.5.8"
   resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.8.tgz#8268a8c57a3e4abd25c165ecd36237db7948a55e"
   integrity sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==
@@ -8770,14 +8749,14 @@
     regenerator-runtime "^0.14.1"
     systemjs "^6.15.1"
 
-"@vitejs/plugin-react@4.3.0":
-  version "4.3.0"
-  resolved "https://registry.yarnpkg.com/@vitejs/plugin-react/-/plugin-react-4.3.0.tgz#f20ec2369a92d8abaaefa60da8b7157819d20481"
-  integrity sha512-KcEbMsn4Dpk+LIbHMj7gDPRKaTMStxxWRkRmxsg/jVdFdJCZWt1SchZcf0M4t8lIKdwwMsEyzhrcOXRrDPtOBw==
+"@vitejs/plugin-react@4.3.3":
+  version "4.3.3"
+  resolved "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.3.3.tgz#28301ac6d7aaf20b73a418ee5c65b05519b4836c"
+  integrity sha512-NooDe9GpHGqNns1i8XDERg0Vsg5SSYRhRxxyTGogUdkdNt47jal+fbuYi+Yfq6pzRCKXyoPcWisfxE6RIM3GKA==
   dependencies:
-    "@babel/core" "^7.24.5"
-    "@babel/plugin-transform-react-jsx-self" "^7.24.5"
-    "@babel/plugin-transform-react-jsx-source" "^7.24.1"
+    "@babel/core" "^7.25.2"
+    "@babel/plugin-transform-react-jsx-self" "^7.24.7"
+    "@babel/plugin-transform-react-jsx-source" "^7.24.7"
     "@types/babel__core" "^7.20.5"
     react-refresh "^0.14.2"
 
@@ -10624,7 +10603,7 @@ axios@0.21.2:
   dependencies:
     follow-redirects "^1.14.0"
 
-axios@^1.7.4:
+axios@1.7.7, axios@^1.7.4:
   version "1.7.7"
   resolved "https://registry.yarnpkg.com/axios/-/axios-1.7.7.tgz#2f554296f9892a72ac8d8e4c5b79c14a91d0a47f"
   integrity sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==
@@ -22513,7 +22492,7 @@ mobx@6.13.5:
   resolved "https://registry.npmjs.org/mobx/-/mobx-6.13.5.tgz#957d9df88c7f8b4baa7c6f8bdcb6d68b432a6ed5"
   integrity sha512-/HTWzW2s8J1Gqt+WmUj5Y0mddZk+LInejADc79NJadrWla3rHzmRHki/mnEUH1AvOmbNTZ1BRbKxr8DSgfdjMA==
 
-"mocha-7.0.1@npm:mocha@7.0.1":
+"mocha-7.0.1@npm:mocha@7.0.1", mocha@7.0.1:
   version "7.0.1"
   resolved "https://registry.yarnpkg.com/mocha/-/mocha-7.0.1.tgz#276186d35a4852f6249808c6dd4a1376cbf6c6ce"
   integrity sha512-9eWmWTdHLXh72rGrdZjNbG3aa1/3NRPpul1z0D979QpEnFdCG0Q5tv834N+94QEN2cysfV72YocQ3fn87s70fg==
@@ -22630,36 +22609,6 @@ mocha@6.2.2:
     yargs-parser "13.1.1"
     yargs-unparser "1.6.0"
 
-mocha@7.0.1:
-  version "7.0.1"
-  resolved "https://registry.yarnpkg.com/mocha/-/mocha-7.0.1.tgz#276186d35a4852f6249808c6dd4a1376cbf6c6ce"
-  integrity sha512-9eWmWTdHLXh72rGrdZjNbG3aa1/3NRPpul1z0D979QpEnFdCG0Q5tv834N+94QEN2cysfV72YocQ3fn87s70fg==
-  dependencies:
-    ansi-colors "3.2.3"
-    browser-stdout "1.3.1"
-    chokidar "3.3.0"
-    debug "3.2.6"
-    diff "3.5.0"
-    escape-string-regexp "1.0.5"
-    find-up "3.0.0"
-    glob "7.1.3"
-    growl "1.10.5"
-    he "1.2.0"
-    js-yaml "3.13.1"
-    log-symbols "2.2.0"
-    minimatch "3.0.4"
-    mkdirp "0.5.1"
-    ms "2.1.1"
-    node-environment-flags "1.0.6"
-    object.assign "4.1.0"
-    strip-json-comments "2.0.1"
-    supports-color "6.0.0"
-    which "1.3.1"
-    wide-align "1.1.3"
-    yargs "13.3.0"
-    yargs-parser "13.1.1"
-    yargs-unparser "1.6.0"
-
 mocha@7.1.0:
   version "7.1.0"
   resolved "https://registry.yarnpkg.com/mocha/-/mocha-7.1.0.tgz#c784f579ad0904d29229ad6cb1e2514e4db7d249"
@@ -25908,7 +25857,7 @@ prop-types@15.7.2:
     object-assign "^4.1.1"
     react-is "^16.8.1"
 
-prop-types@^15.5.10, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2:
+prop-types@15.8.1, prop-types@^15.5.10, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2:
   version "15.8.1"
   resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
   integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
@@ -26335,25 +26284,6 @@ react-docgen@6.0.4:
     object-assign "^4.1.1"
     prop-types "^15.6.0"
 
-react-dom@16.8.6:
-  version "16.8.6"
-  resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.8.6.tgz#71d6303f631e8b0097f56165ef608f051ff6e10f"
-  integrity sha512-1nL7PIq9LTL3fthPqwkvr2zY7phIPjYrT0jp4HjyEQrEROnw4dG41VVwi/wfoCneoleqrNX7iAD+pXebJZwrwA==
-  dependencies:
-    loose-envify "^1.1.0"
-    object-assign "^4.1.1"
-    prop-types "^15.6.2"
-    scheduler "^0.13.6"
-
-react-dom@17.0.2, react-dom@^17.0.2:
-  version "17.0.2"
-  resolved "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz#ecffb6845e3ad8dbfcdc498f0d0a939736502c23"
-  integrity sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==
-  dependencies:
-    loose-envify "^1.1.0"
-    object-assign "^4.1.1"
-    scheduler "^0.20.2"
-
 react-dom@18.3.1:
   version "18.3.1"
   resolved "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz#c2265d79511b57d479b3dd3fdfa51536494c5cb4"
@@ -26423,20 +26353,20 @@ react-remove-scroll@^2.3.0:
     use-callback-ref "^1.2.3"
     use-sidecar "^1.0.1"
 
-react-router-dom@6.10.0:
-  version "6.10.0"
-  resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.10.0.tgz#090ddc5c84dc41b583ce08468c4007c84245f61f"
-  integrity sha512-E5dfxRPuXKJqzwSe/qGcqdwa18QiWC6f3H3cWXM24qj4N0/beCIf/CWTipop2xm7mR0RCS99NnaqPNjHtrAzCg==
+react-router-dom@6.28.0:
+  version "6.28.0"
+  resolved "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.28.0.tgz#f73ebb3490e59ac9f299377062ad1d10a9f579e6"
+  integrity sha512-kQ7Unsl5YdyOltsPGl31zOjLrDv+m2VcIEcIHqYYD3Lp0UppLjrzcfJqDJwXxFw3TH/yvapbnUvPlAj7Kx5nbg==
   dependencies:
-    "@remix-run/router" "1.5.0"
-    react-router "6.10.0"
+    "@remix-run/router" "1.21.0"
+    react-router "6.28.0"
 
-react-router@6.10.0:
-  version "6.10.0"
-  resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.10.0.tgz#230f824fde9dd0270781b5cb497912de32c0a971"
-  integrity sha512-Nrg0BWpQqrC3ZFFkyewrflCud9dio9ME3ojHCF/WLsprJVzkq3q3UeEhMCAW1dobjeGbWgjNn/PVF6m46ANxXQ==
+react-router@6.28.0:
+  version "6.28.0"
+  resolved "https://registry.npmjs.org/react-router/-/react-router-6.28.0.tgz#29247c86d7ba901d7e5a13aa79a96723c3e59d0d"
+  integrity sha512-HrYdIFqdrnhDw0PqG/AKjAqEqM7AvxCz0DQ4h2W8k6nqmc5uRBYDag0SBxx9iYz5G8gnuNVLzUe13wl9eAsXXg==
   dependencies:
-    "@remix-run/router" "1.5.0"
+    "@remix-run/router" "1.21.0"
 
 react-style-singleton@^2.1.0:
   version "2.1.1"
@@ -26457,24 +26387,6 @@ react-test-renderer@^16.0.0-0:
     react-is "^16.8.6"
     scheduler "^0.19.1"
 
-react@16.8.6:
-  version "16.8.6"
-  resolved "https://registry.yarnpkg.com/react/-/react-16.8.6.tgz#ad6c3a9614fd3a4e9ef51117f54d888da01f2bbe"
-  integrity sha512-pC0uMkhLaHm11ZSJULfOBqV4tIZkx87ZLvbbQYunNixAAvjnC+snJCg0XQXn9VIsttVsbZP/H/ewzgsd5fxKXw==
-  dependencies:
-    loose-envify "^1.1.0"
-    object-assign "^4.1.1"
-    prop-types "^15.6.2"
-    scheduler "^0.13.6"
-
-react@17.0.2, react@^17.0.2:
-  version "17.0.2"
-  resolved "https://registry.npmjs.org/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037"
-  integrity sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==
-  dependencies:
-    loose-envify "^1.1.0"
-    object-assign "^4.1.1"
-
 react@18.3.1:
   version "18.3.1"
   resolved "https://registry.npmjs.org/react/-/react-18.3.1.tgz#49ab892009c53933625bd16b2533fc754cab2891"
@@ -27597,14 +27509,6 @@ sax@>=0.6.0, sax@^1.2.4:
   resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
   integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
 
-scheduler@^0.13.6:
-  version "0.13.6"
-  resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.13.6.tgz#466a4ec332467b31a91b9bf74e5347072e4cd889"
-  integrity sha512-IWnObHt413ucAYKsD9J1QShUKkbKLQQHdxRyw73sw4FN26iWr3DY/H34xGPe4nmL1DwXyWmSWmMrA9TfQbE/XQ==
-  dependencies:
-    loose-envify "^1.1.0"
-    object-assign "^4.1.1"
-
 scheduler@^0.19.1:
   version "0.19.1"
   resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.19.1.tgz#4f3e2ed2c1a7d65681f4c854fa8c5a1ccb40f196"
@@ -27613,14 +27517,6 @@ scheduler@^0.19.1:
     loose-envify "^1.1.0"
     object-assign "^4.1.1"
 
-scheduler@^0.20.2:
-  version "0.20.2"
-  resolved "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz#4baee39436e34aa93b4874bddcbf0fe8b8b50e91"
-  integrity sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==
-  dependencies:
-    loose-envify "^1.1.0"
-    object-assign "^4.1.1"
-
 scheduler@^0.23.2:
   version "0.23.2"
   resolved "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz#414ba64a3b282892e944cf2108ecc078d115cdc3"
@@ -29282,7 +29178,7 @@ string-template@~0.2.1:
   resolved "https://registry.yarnpkg.com/string-template/-/string-template-0.2.1.tgz#42932e598a352d01fc22ec3367d9d84eec6c9add"
   integrity sha1-QpMuWYo1LQH8IuwzZ9nYTuxsmt0=
 
-"string-width-cjs@npm:string-width@^4.2.0":
+"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
   version "4.2.3"
   resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
   integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
@@ -29308,15 +29204,6 @@ string-width@^1.0.1, string-width@^1.0.2:
     is-fullwidth-code-point "^2.0.0"
     strip-ansi "^4.0.0"
 
-"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
-  version "4.2.3"
-  resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
-  integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
-  dependencies:
-    emoji-regex "^8.0.0"
-    is-fullwidth-code-point "^3.0.0"
-    strip-ansi "^6.0.1"
-
 string-width@^3.0.0, string-width@^3.1.0:
   version "3.1.0"
   resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961"
@@ -29427,7 +29314,7 @@ stringify-object@^3.0.0, stringify-object@^3.3.0:
     is-obj "^1.0.1"
     is-regexp "^1.0.0"
 
-"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
+"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@6.0.1, strip-ansi@^6.0.0, strip-ansi@^6.0.1:
   version "6.0.1"
   resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
   integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
@@ -29448,13 +29335,6 @@ strip-ansi@5.2.0, strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0:
   dependencies:
     ansi-regex "^4.1.0"
 
-strip-ansi@6.0.1, strip-ansi@^6.0.0, strip-ansi@^6.0.1:
-  version "6.0.1"
-  resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
-  integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
-  dependencies:
-    ansi-regex "^5.0.1"
-
 strip-ansi@^3.0.0, strip-ansi@^3.0.1:
   version "3.0.1"
   resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
@@ -31785,7 +31665,7 @@ vite@5.2.11:
   optionalDependencies:
     fsevents "~2.3.3"
 
-vite@^5.0.0:
+vite@5.4.10, vite@^5.0.0:
   version "5.4.10"
   resolved "https://registry.npmjs.org/vite/-/vite-5.4.10.tgz#d358a7bd8beda6cf0f3b7a450a8c7693a4f80c18"
   integrity sha512-1hvaPshuPUtxeQ0hsVH3Mud0ZanOLwVTneA1EgbAM5LhaZEqyPWGRQ7BtaMvUrTDeEaC8pxtj6a6jku3x4z6SQ==
@@ -32459,7 +32339,7 @@ workerpool@6.2.0:
   resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.0.tgz#827d93c9ba23ee2019c3ffaff5c27fccea289e8b"
   integrity sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==
 
-"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
+"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0:
   version "7.0.0"
   resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
   integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
@@ -32502,15 +32382,6 @@ wrap-ansi@^6.2.0:
     string-width "^4.1.0"
     strip-ansi "^6.0.0"
 
-wrap-ansi@^7.0.0:
-  version "7.0.0"
-  resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
-  integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
-  dependencies:
-    ansi-styles "^4.0.0"
-    string-width "^4.1.0"
-    strip-ansi "^6.0.0"
-
 wrap-ansi@^8.0.1, wrap-ansi@^8.1.0:
   version "8.1.0"
   resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"

From 90da84a3b556a58952cc654b6a374f7dfa9b7707 Mon Sep 17 00:00:00 2001
From: AtofStryker <bglesias@gmail.com>
Date: Fri, 15 Nov 2024 11:28:11 -0500
Subject: [PATCH 2/2] update tests / suggestions from code review [run ci]

---
 .../cypress/component/advanced/hooks/counter2-with-hooks.jsx    | 2 +-
 npm/react/cypress/component/advanced/mocking-axios/1-users.jsx  | 1 -
 .../cypress/component/advanced/mocking-axios/2-users-api.jsx    | 1 -
 .../cypress/component/advanced/renderless/mouse-movement.jsx    | 2 +-
 .../cypress/component/advanced/set-timeout-example/App.jsx      | 2 +-
 .../component/advanced/set-timeout-example/LoadingIndicator.jsx | 2 +-
 6 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/npm/react/cypress/component/advanced/hooks/counter2-with-hooks.jsx b/npm/react/cypress/component/advanced/hooks/counter2-with-hooks.jsx
index 8d12775ee3c6..12fee25c14a3 100644
--- a/npm/react/cypress/component/advanced/hooks/counter2-with-hooks.jsx
+++ b/npm/react/cypress/component/advanced/hooks/counter2-with-hooks.jsx
@@ -6,7 +6,7 @@ export default function Counter2WithHooks () {
 
   useEffect(() => {
     document.title = `You clicked ${count} times`
-  })
+  }, [count])
 
   return (
     <div>
diff --git a/npm/react/cypress/component/advanced/mocking-axios/1-users.jsx b/npm/react/cypress/component/advanced/mocking-axios/1-users.jsx
index 0e896fa1d0ed..4286947f6674 100644
--- a/npm/react/cypress/component/advanced/mocking-axios/1-users.jsx
+++ b/npm/react/cypress/component/advanced/mocking-axios/1-users.jsx
@@ -8,7 +8,6 @@ export function Users () {
 
   const getUsers = async () => {
     const response = await axios.get('https://jsonplaceholder.cypress.io/users?_limit=3')
-    // JSON responses are automatically parsed.
 
     setUsers(response.data)
   }
diff --git a/npm/react/cypress/component/advanced/mocking-axios/2-users-api.jsx b/npm/react/cypress/component/advanced/mocking-axios/2-users-api.jsx
index 96fcbc13c075..f8d2274fdf7b 100644
--- a/npm/react/cypress/component/advanced/mocking-axios/2-users-api.jsx
+++ b/npm/react/cypress/component/advanced/mocking-axios/2-users-api.jsx
@@ -8,7 +8,6 @@ export function Users () {
   const getUsers = async () => {
     console.log({ axiosApi })
     const response = await axiosApi.get('https://jsonplaceholder.cypress.io/users?_limit=3')
-    // JSON responses are automatically parsed.
 
     setUsers(response.data)
   }
diff --git a/npm/react/cypress/component/advanced/renderless/mouse-movement.jsx b/npm/react/cypress/component/advanced/renderless/mouse-movement.jsx
index 609337969ec5..7782e8f44d69 100644
--- a/npm/react/cypress/component/advanced/renderless/mouse-movement.jsx
+++ b/npm/react/cypress/component/advanced/renderless/mouse-movement.jsx
@@ -36,7 +36,7 @@ export default function MouseMovement ({ onMoved }) {
       clearTimeout(timer)
       setTimer(undefined)
     }
-  })
+  }, [])
 
   return null
 }
diff --git a/npm/react/cypress/component/advanced/set-timeout-example/App.jsx b/npm/react/cypress/component/advanced/set-timeout-example/App.jsx
index 6346e91ba177..c0cd7c76af93 100644
--- a/npm/react/cypress/component/advanced/set-timeout-example/App.jsx
+++ b/npm/react/cypress/component/advanced/set-timeout-example/App.jsx
@@ -12,7 +12,7 @@ function App () {
     return () => {
       clearTimeout(_timer)
     }
-  })
+  }, [])
 
   return (
     <div className="App">
diff --git a/npm/react/cypress/component/advanced/set-timeout-example/LoadingIndicator.jsx b/npm/react/cypress/component/advanced/set-timeout-example/LoadingIndicator.jsx
index b5efe7a250d9..f4a57d7431c6 100644
--- a/npm/react/cypress/component/advanced/set-timeout-example/LoadingIndicator.jsx
+++ b/npm/react/cypress/component/advanced/set-timeout-example/LoadingIndicator.jsx
@@ -12,7 +12,7 @@ export default function LoadingIndicator ({ isLoading, children }) {
     return () => {
       clearTimeout(_delayTimer)
     }
-  })
+  }, [])
 
   if (isLoading) {
     if (!isPastDelay) {