Skip to content

Commit 310b08a

Browse files
ThomasRoestThomas Roest
and
Thomas Roest
authored
Upgrade to React 18 (#2087) (#2110)
Upgrade to React 18 * replace ReactDOM.render with createRoot in index.ts * fix new TS errors after upgrading @types * replace ReactDOM.render in Preview.tsx * replace ReactDOM.unmountComponentAtNode with root.unmount() * remove ReactDOM import * upgrade react testing library * replace deprecated React.SFC type with React.FC DefinitelyTyped/DefinitelyTyped#30364 * Fix TS errors in propTypes.children propTypes.node results in TS errors. There doesn't seem to be a good alternative ( other than making the children propTypes more strict, which could result more errors) Instead use something less restrictive (propTypes.any) for children and components. * fix TS errors, extract props interfaces with children * fix TS errors, add context types * TS fix * Fix React unmount error Unmount asynchronously with setTimout https://stackoverflow.com/questions/73459382/react-18-async-way-to-unmount-root error message: Warning: Attempted to synchronously unmount a root while React was already rendering. React cannot finish unmounting the root until the current render has completed, which may lead to a race condition. * make wrapper unmount test async --------- Co-authored-by: Thomas Roest <[email protected]>
1 parent 2ba612a commit 310b08a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+758
-653
lines changed

package-lock.json

+603-544
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+6-6
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@
106106
"@babel/preset-react": "^7.18.6",
107107
"@babel/preset-typescript": "^7.18.6",
108108
"@testing-library/jest-dom": "^5.11.4",
109-
"@testing-library/react": "^11.1.0",
109+
"@testing-library/react": "^13.4.0",
110110
"@types/buble": "^0.19.2",
111111
"@types/copy-webpack-plugin": "^5.0.2",
112112
"@types/doctrine": "0.0.3",
@@ -119,8 +119,8 @@
119119
"@types/markdown-to-jsx": "^6.9.0",
120120
"@types/node": "^12.12.3",
121121
"@types/prismjs": "^1.16.0",
122-
"@types/react": "^16.9.27",
123-
"@types/react-dom": "^16.9.5",
122+
"@types/react": "^18.0.26",
123+
"@types/react-dom": "^18.0.9",
124124
"@types/terser-webpack-plugin": "^2.2.3",
125125
"@types/type-detect": "^4.0.1",
126126
"@types/webpack": "^5.28.0",
@@ -153,9 +153,9 @@
153153
"memfs": "~2.15.5",
154154
"prettier": "2.1.2",
155155
"raf": "^3.4.1",
156-
"react": "^17.0.2",
157-
"react-dom": "^17.0.2",
158-
"react-test-renderer": "^17.0.2",
156+
"react": "^18.2.0",
157+
"react-dom": "^18.2.0",
158+
"react-test-renderer": "^18.2.0",
159159
"strip-shebang": "^1.0.2",
160160
"style-loader": "^3.3.1",
161161
"typescript": "^4.7.4",

src/client/index.ts

+13-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* eslint-disable import/first */
22
import './polyfills';
33
import './styles';
4-
import ReactDOM from 'react-dom';
4+
import { createRoot, Root } from 'react-dom/client';
55
import renderStyleguide from './utils/renderStyleguide';
66
import { getParameterByName, hasInHash, getHash } from './utils/handleHash';
77

@@ -33,14 +33,22 @@ const scrollToOrigin = () => {
3333
}
3434
};
3535

36+
let reactRoot: Root | null = null;
37+
3638
const render = () => {
3739
// eslint-disable-next-line @typescript-eslint/no-var-requires
3840
const styleguide = require('!!../loaders/styleguide-loader!./index.js');
3941

40-
ReactDOM.render(
41-
renderStyleguide(styleguide, codeRevision),
42-
document.getElementById(styleguide.config.mountPointId)
43-
);
42+
if (!reactRoot) {
43+
const rootNode = document.getElementById(styleguide.config.mountPointId);
44+
if (rootNode) {
45+
reactRoot = createRoot(rootNode);
46+
}
47+
}
48+
49+
if (reactRoot) {
50+
reactRoot.render(renderStyleguide(styleguide, codeRevision));
51+
}
4452
};
4553

4654
window.addEventListener('hashchange', render);

src/client/rsg-components/Code/CodeRenderer.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export const CodeRenderer: React.FunctionComponent<CodeProps> = ({ classes, chil
2222
};
2323
CodeRenderer.propTypes = {
2424
classes: PropTypes.objectOf(PropTypes.string.isRequired).isRequired,
25-
children: PropTypes.node.isRequired,
25+
children: PropTypes.any.isRequired,
2626
};
2727

2828
export default Styled<CodeProps>(styles)(CodeRenderer);

src/client/rsg-components/Examples/ExamplesRenderer.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export const ExamplesRenderer: React.FunctionComponent<ExamplesRendererProps> =
2727
ExamplesRenderer.propTypes = {
2828
classes: PropTypes.objectOf(PropTypes.string.isRequired).isRequired,
2929
name: PropTypes.string.isRequired,
30-
children: PropTypes.node,
30+
children: PropTypes.any,
3131
};
3232

3333
export default Styled<ExamplesRendererProps>(styles)(ExamplesRenderer);

src/client/rsg-components/Heading/HeadingRenderer.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ const HeadingRenderer: React.FunctionComponent<HeadingProps> = ({
4444
children,
4545
...props
4646
}) => {
47-
const Tag = `h${level}` as ('h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6');
47+
const Tag = `h${level}` as 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
4848
const headingClasses = cx(classes.heading, classes[`heading${level}`]);
4949

5050
return (
@@ -57,7 +57,7 @@ const HeadingRenderer: React.FunctionComponent<HeadingProps> = ({
5757
HeadingRenderer.propTypes = {
5858
classes: PropTypes.objectOf(PropTypes.string.isRequired).isRequired,
5959
level: PropTypes.oneOf([1, 2, 3, 4, 5, 6]).isRequired,
60-
children: PropTypes.node,
60+
children: PropTypes.any,
6161
};
6262

6363
export default Styled<HeadingProps>(styles)(HeadingRenderer);

src/client/rsg-components/Link/LinkRenderer.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export const LinkRenderer: React.FunctionComponent<LinkProps> = ({
4141

4242
LinkRenderer.propTypes = {
4343
classes: PropTypes.objectOf(PropTypes.string.isRequired).isRequired,
44-
children: PropTypes.node,
44+
children: PropTypes.any,
4545
className: PropTypes.string,
4646
href: PropTypes.string,
4747
};

src/client/rsg-components/Logo/LogoRenderer.tsx

+5-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,11 @@ const styles = ({ color, fontFamily, fontSize }: Rsg.Theme) => ({
1212
},
1313
});
1414

15-
export const LogoRenderer: React.FunctionComponent<JssInjectedProps> = ({ classes, children }) => {
15+
interface Props extends JssInjectedProps {
16+
children?: React.ReactNode;
17+
}
18+
19+
export const LogoRenderer = ({ classes, children }: Props) => {
1620
return <h1 className={classes.logo}>{children}</h1>;
1721
};
1822

src/client/rsg-components/Markdown/Blockquote/BlockquoteRenderer.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ export const BlockquoteRenderer: React.FunctionComponent<BlockquoteProps> = ({
3232
BlockquoteRenderer.propTypes = {
3333
classes: PropTypes.objectOf(PropTypes.string.isRequired).isRequired,
3434
className: PropTypes.string,
35-
children: PropTypes.node.isRequired,
35+
children: PropTypes.any.isRequired,
3636
};
3737

3838
export default Styled<BlockquoteProps>(styles)(BlockquoteRenderer);

src/client/rsg-components/Markdown/Details/DetailsRenderer.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export const DetailsRenderer: React.FunctionComponent<DetailsProps> = ({ classes
2222

2323
DetailsRenderer.propTypes = {
2424
classes: PropTypes.objectOf(PropTypes.string.isRequired).isRequired,
25-
children: PropTypes.node.isRequired,
25+
children: PropTypes.any.isRequired,
2626
};
2727

2828
export default Styled<DetailsProps>(styles)(DetailsRenderer);

src/client/rsg-components/Markdown/Details/DetailsSummaryRenderer.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ export const DetailsSummaryRenderer: React.FunctionComponent<DetailsSummaryProps
3232

3333
DetailsSummaryRenderer.propTypes = {
3434
classes: PropTypes.objectOf(PropTypes.string.isRequired).isRequired,
35-
children: PropTypes.node.isRequired,
35+
children: PropTypes.any.isRequired,
3636
};
3737

3838
export default Styled<DetailsSummaryProps>(styles)(DetailsSummaryRenderer);

src/client/rsg-components/Markdown/List/ListRenderer.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export const ListRenderer: React.FunctionComponent<ListProps> = ({
3939

4040
return (
4141
<Tag className={classNames}>
42-
{Children.map(children, li =>
42+
{Children.map(children, (li) =>
4343
React.isValidElement(li) ? cloneElement(li, { className: classes.li }) : li
4444
)}
4545
</Tag>
@@ -48,7 +48,7 @@ export const ListRenderer: React.FunctionComponent<ListProps> = ({
4848
ListRenderer.propTypes = {
4949
classes: PropTypes.objectOf(PropTypes.string.isRequired).isRequired,
5050
ordered: PropTypes.bool,
51-
children: PropTypes.node.isRequired,
51+
children: PropTypes.any.isRequired,
5252
};
5353
ListRenderer.defaultProps = {
5454
ordered: false,

src/client/rsg-components/Markdown/Markdown.tsx

+26-26
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { isValidElement } from 'react';
1+
import React, { isValidElement, PropsWithChildren } from 'react';
22
import PropTypes from 'prop-types';
33
import { compiler } from 'markdown-to-jsx';
44
import stripHtmlComments from 'strip-html-comments';
@@ -28,112 +28,112 @@ Pre.propTypes = {
2828

2929
export const baseOverrides = {
3030
a: {
31-
component: Link as React.SFC,
31+
component: Link as React.FC,
3232
},
3333
h1: {
34-
component: MarkdownHeading as React.SFC,
34+
component: MarkdownHeading as React.FC,
3535
props: {
3636
level: 1,
3737
},
3838
},
3939
h2: {
40-
component: MarkdownHeading as React.SFC,
40+
component: MarkdownHeading as React.FC,
4141
props: {
4242
level: 2,
4343
},
4444
},
4545
h3: {
46-
component: MarkdownHeading as React.SFC,
46+
component: MarkdownHeading as React.FC,
4747
props: {
4848
level: 3,
4949
},
5050
},
5151
h4: {
52-
component: MarkdownHeading as React.SFC,
52+
component: MarkdownHeading as React.FC,
5353
props: {
5454
level: 4,
5555
},
5656
},
5757
h5: {
58-
component: MarkdownHeading as React.SFC,
58+
component: MarkdownHeading as React.FC,
5959
props: {
6060
level: 5,
6161
},
6262
},
6363
h6: {
64-
component: MarkdownHeading as React.SFC,
64+
component: MarkdownHeading as React.FC,
6565
props: {
6666
level: 6,
6767
},
6868
},
6969
p: {
70-
component: Para as React.SFC,
70+
component: Para as React.FC,
7171
props: {
7272
semantic: 'p',
7373
},
7474
},
7575
em: {
76-
component: Text as React.SFC,
76+
component: Text as React.FC,
7777
props: {
7878
semantic: 'em',
7979
},
8080
},
8181
strong: {
82-
component: Text as React.SFC,
82+
component: Text as React.FC,
8383
props: {
8484
semantic: 'strong',
8585
},
8686
},
8787
ul: {
88-
component: List as React.SFC,
88+
component: List as React.FC,
8989
},
9090
ol: {
91-
component: List as React.SFC,
91+
component: List as React.FC,
9292
props: {
9393
ordered: true,
9494
},
9595
},
9696
blockquote: {
97-
component: Blockquote as React.SFC,
97+
component: Blockquote as React.FC,
9898
},
9999
code: {
100-
component: Code as React.SFC,
100+
component: Code as React.FC,
101101
},
102102
pre: {
103-
component: Pre as React.SFC,
103+
component: Pre as React.FC<PropsWithChildren>,
104104
},
105105
input: {
106-
component: Checkbox as React.SFC,
106+
component: Checkbox as React.FC,
107107
},
108108
hr: {
109-
component: Hr as React.SFC,
109+
component: Hr as React.FC,
110110
},
111111
table: {
112-
component: Table as React.SFC,
112+
component: Table as React.FC,
113113
},
114114
thead: {
115-
component: TableHead as React.SFC,
115+
component: TableHead as React.FC,
116116
},
117117
th: {
118-
component: TableCell as React.SFC,
118+
component: TableCell as React.FC,
119119
props: {
120120
header: true,
121121
},
122122
},
123123
tbody: {
124-
component: TableBody as React.SFC,
124+
component: TableBody as React.FC,
125125
},
126126
tr: {
127-
component: TableRow as React.SFC,
127+
component: TableRow as React.FC,
128128
},
129129
td: {
130-
component: TableCell as React.SFC,
130+
component: TableCell as React.FC,
131131
},
132132
details: {
133-
component: Details as React.SFC,
133+
component: Details as React.FC,
134134
},
135135
summary: {
136-
component: DetailsSummary as React.SFC,
136+
component: DetailsSummary as React.FC,
137137
},
138138
};
139139

src/client/rsg-components/Markdown/MarkdownHeading/MarkdownHeadingRenderer.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ const MarkdownHeadingRenderer: React.FunctionComponent<MarkdownHeadingProps> = (
3434
MarkdownHeadingRenderer.propTypes = {
3535
classes: PropTypes.objectOf(PropTypes.string.isRequired).isRequired,
3636
level: PropTypes.oneOf([1, 2, 3, 4, 5, 6]).isRequired,
37-
children: PropTypes.node,
37+
children: PropTypes.any,
3838
id: PropTypes.string,
3939
};
4040

src/client/rsg-components/Markdown/Pre/PreRenderer.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ export const PreRenderer: React.FunctionComponent<PrePropsWithClasses> = ({
5050
PreRenderer.propTypes = {
5151
classes: PropTypes.objectOf(PropTypes.string.isRequired).isRequired,
5252
className: PropTypes.string,
53-
children: PropTypes.node.isRequired,
53+
children: PropTypes.any.isRequired,
5454
};
5555

5656
export default Styled<PrePropsWithClasses>(styles)(PreRenderer);

src/client/rsg-components/Markdown/Table/TableBodyRenderer.tsx

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
import React from 'react';
22
import PropTypes from 'prop-types';
33

4-
export const TableBodyRenderer: React.FunctionComponent = ({ children }) => {
4+
interface Props {
5+
children?: React.ReactNode;
6+
}
7+
8+
export const TableBodyRenderer = ({ children }: Props) => {
59
return <tbody>{children}</tbody>;
610
};
711
TableBodyRenderer.propTypes = {

src/client/rsg-components/Markdown/Table/TableCellRenderer.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ export const TableCellRenderer: React.FunctionComponent<TableCellProps> = ({
3737
TableCellRenderer.propTypes = {
3838
classes: PropTypes.objectOf(PropTypes.string.isRequired).isRequired,
3939
header: PropTypes.bool,
40-
children: PropTypes.node.isRequired,
40+
children: PropTypes.any.isRequired,
4141
};
4242
TableCellRenderer.defaultProps = {
4343
header: false,

src/client/rsg-components/Markdown/Table/TableHeadRenderer.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export const TableHeadRenderer: React.FunctionComponent<TableHeadProps> = ({
2222

2323
TableHeadRenderer.propTypes = {
2424
classes: PropTypes.objectOf(PropTypes.string.isRequired).isRequired,
25-
children: PropTypes.node.isRequired,
25+
children: PropTypes.any.isRequired,
2626
};
2727

2828
export default Styled<TableHeadProps>(styles)(TableHeadRenderer);

src/client/rsg-components/Markdown/Table/TableRenderer.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export const TableRenderer: React.FunctionComponent<TableProps> = ({ classes, ch
2121

2222
TableRenderer.propTypes = {
2323
classes: PropTypes.objectOf(PropTypes.string.isRequired).isRequired,
24-
children: PropTypes.node.isRequired,
24+
children: PropTypes.any.isRequired,
2525
};
2626

2727
export default Styled<TableProps>(styles)(TableRenderer);

src/client/rsg-components/Markdown/Table/TableRowRenderer.tsx

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
import React from 'react';
22
import PropTypes from 'prop-types';
33

4-
export const TableRowRenderer: React.FunctionComponent = ({ children }) => {
4+
interface Props {
5+
children?: React.ReactNode;
6+
}
7+
8+
export const TableRowRenderer = ({ children }: Props) => {
59
return <tr>{children}</tr>;
610
};
711
TableRowRenderer.propTypes = {

src/client/rsg-components/Message/MessageRenderer.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ export const MessageRenderer: React.FunctionComponent<MessageProps> = ({ classes
3232

3333
MessageRenderer.propTypes = {
3434
classes: PropTypes.objectOf(PropTypes.string.isRequired).isRequired,
35-
children: PropTypes.node.isRequired,
35+
children: PropTypes.any.isRequired,
3636
};
3737

3838
export default Styled<MessageProps>(styles)(MessageRenderer);

0 commit comments

Comments
 (0)