Skip to content

Commit e98476c

Browse files
authored
fix: 修复 react 17 中报错问题 (#216) (#217)
1 parent 868d784 commit e98476c

File tree

5 files changed

+26
-15
lines changed

5 files changed

+26
-15
lines changed

README.md

+2-3
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,13 @@ import Button from '@uiw/react-button';
2828
import CodePreview from '@uiw/react-code-preview';
2929

3030
const code = `import Button from '@uiw/react-button';
31-
import ReactDOMClient from 'react-dom/client';
31+
import ReactDOM from 'react-dom/client';
3232
33-
ReactDOM.render(
33+
ReactDOM.createRoot(_mount_).render(
3434
<div>
3535
<Button type="primary">主要按钮</Button>
3636
<Button type="success">成功按钮</Button>
3737
</div>,
38-
_mount_
3938
);`;
4039

4140
export default function App() {

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -102,4 +102,4 @@
102102
"last 1 safari version"
103103
]
104104
}
105-
}
105+
}

src/index.less

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
border-radius: 3px;
3131
margin-bottom: 16px;
3232
background-color: var(--color-code-preview-bg) !important;
33-
color: transparent !important;
33+
// color: transparent !important;
3434
max-height: 420px;
3535
min-height: 12px;
3636
z-index: 10;

src/useCodePreview.ts

+19-6
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,19 @@
11
import React, { useEffect, useRef } from 'react';
2-
// @ts-ignore
3-
import ReactDOMClient from 'react-dom/client';
4-
import ReactDOM from 'react-dom';
52
import { useState } from 'react';
63
import { babelTransform } from './transform';
74
import { CodePreviewProps } from './';
5+
import ReactDOM from 'react-dom';
6+
7+
export const getReactDOMClient = () => {
8+
let _ReactDOM;
9+
try {
10+
// 使用 require 解决 react v17 ts 报错问题
11+
_ReactDOM = require('react-dom/client');
12+
} catch (err) {
13+
// console.warn(`如果使用的是react-dom小于v18的版本,可以忽略此警告:${err}`)
14+
}
15+
return _ReactDOM;
16+
};
817

918
export function useCodePreview(props: CodePreviewProps) {
1019
const [demoDom, setDemoDom] = useState<HTMLDivElement>();
@@ -16,6 +25,10 @@ export function useCodePreview(props: CodePreviewProps) {
1625
const [copied, setCopied] = useState(false);
1726
const [code, setCode] = useState(props.code || '');
1827

28+
const ReactDOMClient = React.useMemo(() => {
29+
return window.ReactDOM ? window.ReactDOM : getReactDOMClient();
30+
}, []);
31+
1932
/** 通过缓存的方式 解决 react v18 中 的报错 ***/
2033
// @ts-ignore
2134
const cachesRef = React.useRef(new Map<string, ReactDOMClient.Root>([]));
@@ -51,9 +64,9 @@ export function useCodePreview(props: CodePreviewProps) {
5164
ReactDOMClient: _ReactDOMClient,
5265
...otherDeps
5366
} = props.dependencies || {};
54-
const V18ReactDOM = _ReactDOMClient || ReactDOMClient || _ReactDOM || ReactDOM;
67+
let V18ReactDOM = _ReactDOMClient || ReactDOMClient || _ReactDOM || ReactDOM;
5568
// 判断是否是 react v18版本
56-
const isV18 = Reflect.has(V18ReactDOM || {}, 'createRoot');
69+
const isV18 = Reflect.has(V18ReactDOM, 'createRoot');
5770
const NewReactDOM = isV18 ? ReactDOMRender(V18ReactDOM) : V18ReactDOM;
5871

5972
try {
@@ -75,7 +88,7 @@ export function useCodePreview(props: CodePreviewProps) {
7588
// react < v18 中写法替换
7689
str = str.replace('ReactDOM.render', `ReactDOM.createRoot("${playerId.current}").render`);
7790
// react v18 中写法替换
78-
str = str.replace(`ReactDOMClient.createRoot(_mount_)`, `ReactDOM.createRoot("${playerId.current}")`);
91+
str = str.replace(`ReactDOM.createRoot(_mount_)`, `ReactDOM.createRoot("${playerId.current}")`);
7992
str = str.replace('_mount_', ``);
8093
} else {
8194
str = str.replace('_mount_', `document.getElementById('${playerId.current}')`);

website/Example.tsx

+3-4
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ import * as UIW from 'uiw';
55

66
const defaultCode = `
77
import { Button, Divider, Icon } from 'uiw';
8-
import ReactDOMClient from 'react-dom/client';
8+
import ReactDOM from 'react-dom/client';
99
10-
ReactDOM.render(
10+
ReactDOM.createRoot(_mount_).render(
1111
<div>
1212
<Button type="primary">主要按钮</Button>
1313
<Button type="success">成功按钮</Button>
@@ -16,7 +16,6 @@ ReactDOM.render(
1616
<Button type="light">亮按钮</Button>
1717
<Button type="dark">暗按钮</Button>
1818
</div>,
19-
_mount_
2019
);`;
2120

2221
const Example = () => {
@@ -81,7 +80,7 @@ const Example = () => {
8180
html: '<div id="root"></div>',
8281
js: code.replace('_mount_', 'document.getElementById("root")'),
8382
css_external: 'https://unpkg.com/[email protected]/dist/uiw.min.css',
84-
js_external: `https://unpkg.com/react@16.x/umd/react.development.js;https://unpkg.com/react-dom@16.x/umd/react-dom.development.js;https://unpkg.com/[email protected]/dist/uiw.min.js;https://unpkg.com/@uiw/[email protected]/index.js`,
83+
js_external: `https://unpkg.com/react@18.x/umd/react.development.js;https://unpkg.com/react-dom@18.x/umd/react-dom.development.js;https://unpkg.com/[email protected]/dist/uiw.min.js;https://unpkg.com/@uiw/[email protected]/index.js`,
8584
},
8685
});
8786
function handleChange(keyName: string, e: React.ChangeEvent<HTMLInputElement>) {

0 commit comments

Comments
 (0)