feat: upgrade to react 18 (#593)

This commit is contained in:
Brian Smith
2025-04-04 10:24:46 -04:00
committed by GitHub
parent 78c5d73900
commit 6b8cd1f780
6 changed files with 3414 additions and 2104 deletions

5374
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -35,7 +35,7 @@
"@edx/frontend-enterprise-hotjar": "7.2.0",
"@edx/frontend-platform": "^8.3.1",
"@edx/openedx-atlas": "^0.6.0",
"@edx/react-unit-test-utils": "^3.1.0",
"@edx/react-unit-test-utils": "^4.0.0",
"@fortawesome/fontawesome-svg-core": "^1.2.36",
"@fortawesome/free-brands-svg-icons": "^5.15.4",
"@fortawesome/free-solid-svg-icons": "^5.15.4",
@@ -54,8 +54,8 @@
"moment": "^2.29.4",
"prop-types": "15.8.1",
"query-string": "7.1.3",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-helmet": "^6.1.0",
"react-intl": "6.8.9",
"react-redux": "^7.2.4",
@@ -73,8 +73,8 @@
"@edx/browserslist-config": "^1.3.0",
"@edx/reactifex": "^2.1.1",
"@openedx/frontend-build": "^14.3.3",
"@testing-library/jest-dom": "^5.14.1",
"@testing-library/react": "^12.1.0",
"@testing-library/jest-dom": "^6.6.3",
"@testing-library/react": "^16.2.0",
"copy-webpack-plugin": "^12.0.0",
"identity-obj-proxy": "^3.0.0",
"jest": "^29.7.0",
@@ -82,7 +82,7 @@
"jest-expect-message": "^1.1.3",
"jest-when": "^3.6.0",
"react-dev-utils": "^12.0.0",
"react-test-renderer": "^17.0.2",
"react-test-renderer": "^18.3.1",
"redux-mock-store": "^1.5.4"
}
}

View File

@@ -1,39 +1,43 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`app registry subscribe: APP_INIT_ERROR. snapshot: displays an ErrorPage to root element 1`] = `
<ErrorPage
message="test-error-message"
/>
<UNDEFINED>
<ErrorPage
message="test-error-message"
/>
</UNDEFINED>
`;
exports[`app registry subscribe: APP_READY. links App to root element 1`] = `
<AppProvider
store={
{
"redux": "store",
<UNDEFINED>
<AppProvider
store={
{
"redux": "store",
}
}
}
>
<NoticesWrapper>
<Routes>
<Route
element={
<PageWrap>
<App />
</PageWrap>
}
path="/"
/>
<Route
element={
<Navigate
replace={true}
to="/"
/>
}
path="*"
/>
</Routes>
</NoticesWrapper>
</AppProvider>
>
<NoticesWrapper>
<Routes>
<Route
element={
<PageWrap>
<App />
</PageWrap>
}
path="/"
/>
<Route
element={
<Navigate
replace={true}
to="/"
/>
}
path="*"
/>
</Routes>
</NoticesWrapper>
</AppProvider>
</UNDEFINED>
`;

View File

@@ -2,8 +2,8 @@
import 'core-js/stable';
import 'regenerator-runtime/runtime';
import React from 'react';
import ReactDOM from 'react-dom';
import React, { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import {
Route, Navigate, Routes,
} from 'react-router-dom';
@@ -30,23 +30,29 @@ import App from './App';
import NoticesWrapper from './components/NoticesWrapper';
subscribe(APP_READY, () => {
ReactDOM.render(
<AppProvider store={store}>
<NoticesWrapper>
<Routes>
<Route path="/" element={<PageWrap><App /></PageWrap>} />
<Route path="*" element={<Navigate to="/" replace />} />
</Routes>
</NoticesWrapper>
</AppProvider>,
document.getElementById('root'),
const root = createRoot(document.getElementById('root'));
root.render(
<StrictMode>
<AppProvider store={store}>
<NoticesWrapper>
<Routes>
<Route path="/" element={<PageWrap><App /></PageWrap>} />
<Route path="*" element={<Navigate to="/" replace />} />
</Routes>
</NoticesWrapper>
</AppProvider>
</StrictMode>,
);
});
subscribe(APP_INIT_ERROR, (error) => {
ReactDOM.render(
<ErrorPage message={error.message} />,
document.getElementById('root'),
const root = createRoot(document.getElementById('root'));
root.render(
<StrictMode>
<ErrorPage message={error.message} />
</StrictMode>,
);
});

View File

@@ -1,5 +1,3 @@
import { render } from 'react-dom';
import {
APP_INIT_ERROR,
APP_READY,
@@ -11,9 +9,20 @@ import {
import { configuration } from './config';
import * as app from '.';
jest.mock('react-dom', () => ({
render: jest.fn(),
}));
// These need to be var not let so they get hoisted
// and can be used by jest.mock (which is also hoisted)
var mockRender; // eslint-disable-line no-var
var mockCreateRoot; // eslint-disable-line no-var
jest.mock('react-dom/client', () => {
mockRender = jest.fn();
mockCreateRoot = jest.fn(() => ({
render: mockRender,
}));
return ({
createRoot: mockCreateRoot,
});
});
jest.mock('@edx/frontend-platform', () => ({
mergeConfig: jest.fn(),
@@ -32,7 +41,9 @@ describe('app registry', () => {
let getElement;
beforeEach(() => {
render.mockClear();
mockCreateRoot.mockClear();
mockRender.mockClear();
getElement = window.document.getElementById;
window.document.getElementById = jest.fn(id => ({ id }));
});
@@ -44,18 +55,16 @@ describe('app registry', () => {
const callArgs = subscribe.mock.calls[0];
expect(callArgs[0]).toEqual(APP_READY);
callArgs[1]();
const [rendered, target] = render.mock.calls[0];
const [rendered] = mockRender.mock.calls[0];
expect(rendered).toMatchSnapshot();
expect(target).toEqual(document.getElementById('root'));
});
test('subscribe: APP_INIT_ERROR. snapshot: displays an ErrorPage to root element', () => {
const callArgs = subscribe.mock.calls[1];
expect(callArgs[0]).toEqual(APP_INIT_ERROR);
const error = { message: 'test-error-message' };
callArgs[1](error);
const [rendered, target] = render.mock.calls[0];
const [rendered] = mockRender.mock.calls[0];
expect(rendered).toMatchSnapshot();
expect(target).toEqual(document.getElementById('root'));
});
test('initialize is called with requireAuthenticatedUser', () => {
expect(initialize).toHaveBeenCalledTimes(1);

View File

@@ -1,6 +1,5 @@
/* eslint-disable import/no-extraneous-dependencies */
import '@testing-library/jest-dom';
import '@testing-library/jest-dom/extend-expect';
jest.mock('react', () => ({
...jest.requireActual('react'),