1
- import React from 'react'
1
+ import React , { useLayoutEffect , useRef } from 'react'
2
2
import { useStyleRegistry , createStyleRegistry } from './stylesheet-registry'
3
3
import { computeId } from './lib/hash'
4
4
5
5
// Opt-into the new `useInsertionEffect` API in React 18, fallback to `useLayoutEffect`.
6
6
// https://github.com/reactwg/react-18/discussions/110
7
- const useInsertionEffect = React . useInsertionEffect || React . useLayoutEffect
7
+ const useInsertionEffect = React . useInsertionEffect || useLayoutEffect
8
8
9
9
const defaultRegistry =
10
10
typeof window !== 'undefined' ? createStyleRegistry ( ) : undefined
11
11
export default function JSXStyle ( props ) {
12
12
const registry = defaultRegistry ? defaultRegistry : useStyleRegistry ( )
13
+ const insertionEffectCalled = useRef ( false )
13
14
14
- // If `registry` does not exist, we do nothing here.
15
+ // `registry` might not exist while server-side rendering
15
16
if ( ! registry ) {
16
17
return null
17
18
}
@@ -22,6 +23,22 @@ export default function JSXStyle(props) {
22
23
}
23
24
24
25
useInsertionEffect ( ( ) => {
26
+ // ReactDOM removes all DOM during hydration in certain cases
27
+ if ( ! document . head ) {
28
+ return
29
+ }
30
+ registry . add ( props )
31
+ insertionEffectCalled . current = true
32
+ return ( ) => {
33
+ insertionEffectCalled . current = false
34
+ registry . remove ( props )
35
+ }
36
+ } , [ props . id , String ( props . dynamic ) ] )
37
+
38
+ useLayoutEffect ( ( ) => {
39
+ if ( ! document . head || insertionEffectCalled . current ) {
40
+ return
41
+ }
25
42
registry . add ( props )
26
43
return ( ) => {
27
44
registry . remove ( props )
0 commit comments