1
1
import React , { useEffect , useRef } from 'react' ;
2
- // @ts -ignore
3
- import ReactDOMClient from 'react-dom/client' ;
4
- import ReactDOM from 'react-dom' ;
5
2
import { useState } from 'react' ;
6
3
import { babelTransform } from './transform' ;
7
4
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
+ } ;
8
17
9
18
export function useCodePreview ( props : CodePreviewProps ) {
10
19
const [ demoDom , setDemoDom ] = useState < HTMLDivElement > ( ) ;
@@ -16,6 +25,10 @@ export function useCodePreview(props: CodePreviewProps) {
16
25
const [ copied , setCopied ] = useState ( false ) ;
17
26
const [ code , setCode ] = useState ( props . code || '' ) ;
18
27
28
+ const ReactDOMClient = React . useMemo ( ( ) => {
29
+ return window . ReactDOM ? window . ReactDOM : getReactDOMClient ( ) ;
30
+ } , [ ] ) ;
31
+
19
32
/** 通过缓存的方式 解决 react v18 中 的报错 ***/
20
33
// @ts -ignore
21
34
const cachesRef = React . useRef ( new Map < string , ReactDOMClient . Root > ( [ ] ) ) ;
@@ -51,9 +64,9 @@ export function useCodePreview(props: CodePreviewProps) {
51
64
ReactDOMClient : _ReactDOMClient ,
52
65
...otherDeps
53
66
} = props . dependencies || { } ;
54
- const V18ReactDOM = _ReactDOMClient || ReactDOMClient || _ReactDOM || ReactDOM ;
67
+ let V18ReactDOM = _ReactDOMClient || ReactDOMClient || _ReactDOM || ReactDOM ;
55
68
// 判断是否是 react v18版本
56
- const isV18 = Reflect . has ( V18ReactDOM || { } , 'createRoot' ) ;
69
+ const isV18 = Reflect . has ( V18ReactDOM , 'createRoot' ) ;
57
70
const NewReactDOM = isV18 ? ReactDOMRender ( V18ReactDOM ) : V18ReactDOM ;
58
71
59
72
try {
@@ -75,7 +88,7 @@ export function useCodePreview(props: CodePreviewProps) {
75
88
// react < v18 中写法替换
76
89
str = str . replace ( 'ReactDOM.render' , `ReactDOM.createRoot("${ playerId . current } ").render` ) ;
77
90
// react v18 中写法替换
78
- str = str . replace ( `ReactDOMClient .createRoot(_mount_)` , `ReactDOM.createRoot("${ playerId . current } ")` ) ;
91
+ str = str . replace ( `ReactDOM .createRoot(_mount_)` , `ReactDOM.createRoot("${ playerId . current } ")` ) ;
79
92
str = str . replace ( '_mount_' , `` ) ;
80
93
} else {
81
94
str = str . replace ( '_mount_' , `document.getElementById('${ playerId . current } ')` ) ;
0 commit comments