Skip to content

Commit 409c886

Browse files
feat: support React 18 (#763)
1 parent 01bf74c commit 409c886

13 files changed

+4035
-2345
lines changed

example/AuthenticatedPage.jsx

+2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import React, { useContext } from 'react';
22
import { Link } from 'react-router-dom';
33

4+
/* eslint-disable import/no-extraneous-dependencies */
45
import { AppContext } from '@edx/frontend-platform/react';
6+
/* eslint-enable import/no-extraneous-dependencies */
57

68
export default function AuthenticatedPage() {
79
const { authenticatedUser, config } = useContext(AppContext);

example/ExamplePage.jsx

+36-41
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
import React, { Component } from 'react';
1+
import { useContext, useEffect } from 'react';
22
import { Link } from 'react-router-dom';
33

4-
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
4+
/* eslint-disable import/no-extraneous-dependencies */
5+
import { injectIntl, useIntl } from '@edx/frontend-platform/i18n';
56
import { logInfo } from '@edx/frontend-platform/logging';
67
import { AppContext } from '@edx/frontend-platform/react';
78
import { ensureConfig, mergeConfig, getConfig } from '@edx/frontend-platform';
9+
/* eslint-enable import/no-extraneous-dependencies */
810
import messages from './messages';
911

1012
mergeConfig({
@@ -16,48 +18,41 @@ ensureConfig([
1618
'JS_FILE_VAR',
1719
], 'ExamplePage');
1820

19-
class ExamplePage extends Component {
20-
constructor(props, context) {
21-
super(props, context);
22-
23-
logInfo('The example page can log info, which means logging is configured correctly.');
24-
}
25-
26-
renderAuthenticatedUser() {
27-
if (this.context.authenticatedUser === null) {
28-
return null;
29-
}
30-
return (
31-
<div>
32-
<p>Authenticated Username: <strong>{this.context.authenticatedUser.username}</strong></p>
33-
<p>
34-
Authenticated user&apos;s name:
35-
<strong>{this.context.authenticatedUser.name}</strong>
36-
(Only available if user account has been fetched)
37-
</p>
38-
</div>
39-
);
40-
}
41-
42-
render() {
43-
return (
44-
<div>
45-
<h1>{this.context.config.SITE_NAME} example page.</h1>
46-
<p>{this.props.intl.formatMessage(messages['example.message'])}</p>
47-
{this.renderAuthenticatedUser()}
48-
<p>EXAMPLE_VAR env var came through: <strong>{getConfig().EXAMPLE_VAR}</strong></p>
49-
<p>JS_FILE_VAR var came through: <strong>{getConfig().JS_FILE_VAR}</strong></p>
50-
<p>Visit <Link to="/authenticated">authenticated page</Link>.</p>
51-
<p>Visit <Link to="/error_example">error page</Link>.</p>
52-
</div>
53-
);
21+
function AuthenticatedUser() {
22+
const { authenticatedUser } = useContext(AppContext);
23+
if (authenticatedUser === null) {
24+
return null;
5425
}
26+
return (
27+
<div>
28+
<p>Authenticated Username: <strong>{authenticatedUser.username}</strong></p>
29+
<p>
30+
Authenticated user&apos;s name:
31+
<strong>{authenticatedUser.name}</strong>
32+
(Only available if user account has been fetched)
33+
</p>
34+
</div>
35+
);
5536
}
5637

57-
ExamplePage.contextType = AppContext;
38+
function ExamplePage() {
39+
const intl = useIntl();
5840

59-
ExamplePage.propTypes = {
60-
intl: intlShape.isRequired,
61-
};
41+
useEffect(() => {
42+
logInfo('The example page can log info, which means logging is configured correctly.');
43+
}, []);
44+
45+
return (
46+
<div>
47+
<h1>{getConfig().SITE_NAME} example page.</h1>
48+
<p>{intl.formatMessage(messages['example.message'])}</p>
49+
<AuthenticatedUser />
50+
<p>EXAMPLE_VAR env var came through: <strong>{getConfig().EXAMPLE_VAR}</strong></p>
51+
<p>JS_FILE_VAR var came through: <strong>{getConfig().JS_FILE_VAR}</strong></p>
52+
<p>Visit <Link to="/authenticated">authenticated page</Link>.</p>
53+
<p>Visit <Link to="/error_example">error page</Link>.</p>
54+
</div>
55+
);
56+
}
6257

6358
export default injectIntl(ExamplePage);

example/index.jsx

+21-15
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
import React from 'react';
2-
import ReactDOM from 'react-dom';
1+
import { StrictMode } from 'react';
2+
import { createRoot } from 'react-dom/client';
3+
/* eslint-disable import/no-extraneous-dependencies */
34
import {
45
AppProvider,
56
AuthenticatedPageRoute,
@@ -8,30 +9,35 @@ import {
89
} from '@edx/frontend-platform/react';
910
import { APP_INIT_ERROR, APP_READY, initialize } from '@edx/frontend-platform';
1011
import { subscribe } from '@edx/frontend-platform/pubSub';
12+
/* eslint-enable import/no-extraneous-dependencies */
1113
import { Routes, Route } from 'react-router-dom';
1214

1315
import './index.scss';
1416
import ExamplePage from './ExamplePage';
1517
import AuthenticatedPage from './AuthenticatedPage';
1618

19+
const container = document.getElementById('root');
20+
const root = createRoot(container);
21+
1722
subscribe(APP_READY, () => {
18-
ReactDOM.render(
19-
<AppProvider>
20-
<Routes>
21-
<Route path="/" element={<PageWrap><ExamplePage /></PageWrap>} />
22-
<Route
23-
path="/error_example"
24-
element={<PageWrap><ErrorPage message="Test error message" /></PageWrap>}
25-
/>
26-
<Route path="/authenticated" element={<AuthenticatedPageRoute><AuthenticatedPage /></AuthenticatedPageRoute>} />
27-
</Routes>
28-
</AppProvider>,
29-
document.getElementById('root'),
23+
root.render(
24+
<StrictMode>
25+
<AppProvider>
26+
<Routes>
27+
<Route path="/" element={<PageWrap><ExamplePage /></PageWrap>} />
28+
<Route
29+
path="/error_example"
30+
element={<PageWrap><ErrorPage message="Test error message" /></PageWrap>}
31+
/>
32+
<Route path="/authenticated" element={<AuthenticatedPageRoute><AuthenticatedPage /></AuthenticatedPageRoute>} />
33+
</Routes>
34+
</AppProvider>
35+
</StrictMode>,
3036
);
3137
});
3238

3339
subscribe(APP_INIT_ERROR, (error) => {
34-
ReactDOM.render(<ErrorPage message={error.message} />, document.getElementById('root'));
40+
root.render(<ErrorPage message={error.message} />);
3541
});
3642

3743
initialize({

example/messages.js

+2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
/* eslint-disable import/no-extraneous-dependencies */
12
import { defineMessages } from '@edx/frontend-platform/i18n';
3+
/* eslint-enable import/no-extraneous-dependencies */
24

35
const messages = defineMessages({
46
'example.message': {

jest.config.js

+3
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,8 @@ module.exports = createConfig('jest', {
44
setupFilesAfterEnv: [
55
'<rootDir>/src/setupTest.js',
66
],
7+
modulePathIgnorePatterns: [
8+
'<rootDir>/dist/',
9+
],
710
testTimeout: 20000,
811
});

0 commit comments

Comments
 (0)