@@ -2,13 +2,16 @@ import {
2
2
createElement ,
3
3
ComponentType ,
4
4
ExoticComponent ,
5
- Fragment ,
6
- ReactNode ,
5
+ ReactChild ,
6
+ ReactElement ,
7
+ ReactFragment ,
8
+ ReactPortal ,
7
9
useEffect ,
8
10
useState
9
11
} from 'https://esm.sh/react'
10
12
import { useDeno , useRouter } from './hooks.ts'
11
- import util from '../../shared/util.ts'
13
+
14
+ type ReactNode = ReactChild | ReactFragment | ReactPortal
12
15
13
16
/**
14
17
* `withRouter` allows you to use `useRouter` hook with class component.
@@ -53,30 +56,38 @@ export function withDeno<T>(callback: () => (T | Promise<T>), revalidate?: numbe
53
56
}
54
57
}
55
58
59
+ /**
60
+ * `dynamic` allows you to load a component asynchronously.
61
+ *
62
+ * ```tsx
63
+ * const MyLogo = dynamic(() => import('~/components/logo.tsx'))
64
+ * export default function Logo() {
65
+ * return <MyLogo fallback={<p>loading...</p>}/>
66
+ * }
67
+ * ```
68
+ *
69
+ * @param {Function } factory - load factory.
70
+ */
56
71
export function dynamic < T extends ComponentType < any > > (
57
72
factory : ( ) => Promise < { default : T } >
58
73
) : ExoticComponent < T & { fallback ?: ReactNode } > {
59
74
const DynamicComponent = ( { fallback, ...props } : T & { fallback ?: ReactNode } ) => {
60
- const [ Component , setComponent ] = useState < T | null > ( null )
75
+ const [ mod , setMod ] = useState < { default : T } | null > ( null )
61
76
62
77
useEffect ( ( ) => {
63
- factory ( ) . then ( mod => {
64
- setComponent ( mod . default )
65
- } )
78
+ factory ( ) . then ( setMod )
66
79
} , [ ] )
67
80
68
- if ( Component !== null ) {
69
- return createElement ( Component , props )
81
+ if ( mod !== null ) {
82
+ return createElement ( mod . default , props )
70
83
}
71
84
72
85
if ( fallback ) {
73
- return createElement ( Fragment , null , fallback )
86
+ return fallback as unknown as ReactElement
74
87
}
75
88
76
89
return null
77
90
}
78
91
79
- DynamicComponent . $$typeof = util . supportSymbolFor ? Symbol . for ( 'react.element' ) : ( 0xeac7 as unknown as symbol )
80
-
81
- return DynamicComponent
92
+ return DynamicComponent as ExoticComponent < any >
82
93
}
0 commit comments