Skip to content

Commit 0a8389e

Browse files
committed
update main.tsx
1 parent 98c8ad4 commit 0a8389e

File tree

2 files changed

+56
-32
lines changed

2 files changed

+56
-32
lines changed

custom-app/src/main.tsx

Lines changed: 7 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,14 @@
11
import './main.css'
22

3-
import ReactDOM from 'react-dom'
43
import { NavFooter, NavHeader } from './NavHeader'
5-
import React from 'react'
4+
import { onDOMContentMutate, renderInContainer } from './utils'
65

76
function render() {
8-
ReactDOM.render(
9-
React.createElement(NavHeader),
10-
document.getElementById('fern-header'),
11-
)
12-
ReactDOM.render(
13-
React.createElement(NavFooter),
14-
document.getElementById('fern-footer'),
15-
)
7+
// render custom header
8+
renderInContainer(NavHeader, document.getElementById('fern-header'))
9+
10+
// render custom footer
11+
renderInContainer(NavFooter, document.getElementById('fern-footer'))
1612
}
1713

18-
let observations = 0
19-
document.addEventListener('DOMContentLoaded', () => {
20-
console.log('DOMContentLoaded')
21-
render()
22-
new MutationObserver((e, o) => {
23-
render()
24-
for (const item of e) {
25-
if (item.target instanceof HTMLElement) {
26-
const target = item.target
27-
if (target.id === 'fern-header' || target.id === 'fern-footer') {
28-
if (observations < 3) {
29-
// react hydration will trigger a mutation event
30-
observations++
31-
} else {
32-
o.disconnect()
33-
}
34-
break
35-
}
36-
}
37-
}
38-
}).observe(document.body, { childList: true, subtree: true })
39-
})
14+
onDOMContentMutate(render)

custom-app/src/utils.ts

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import { createRoot, type Root } from 'react-dom/client'
2+
import React, { FunctionComponent } from 'react'
3+
4+
// avoid creating multiple roots for the same element
5+
const roots = new WeakMap<HTMLElement, Root>()
6+
function getOrCreateRoot(element: HTMLElement): Root {
7+
let root = roots.get(element)
8+
if (root == null) {
9+
root = createRoot(element, {
10+
identifierPrefix: 'custom-app',
11+
onRecoverableError: console.error,
12+
})
13+
roots.set(element, root)
14+
}
15+
return root
16+
}
17+
18+
export function renderInContainer(Component: FunctionComponent, container: HTMLElement | null | undefined) {
19+
if (container != null) {
20+
const root = getOrCreateRoot(container)
21+
root.render(React.createElement(Component))
22+
}
23+
}
24+
25+
export function onDOMContentMutate(render: () => void) {
26+
// observe DOM changes to re-render the custom header and footer
27+
let observations = 0
28+
document.addEventListener('DOMContentLoaded', () => {
29+
console.log('DOMContentLoaded')
30+
render()
31+
new MutationObserver((e, o) => {
32+
render()
33+
for (const item of e) {
34+
if (item.target instanceof HTMLElement) {
35+
const target = item.target
36+
if (target.id === 'fern-header' || target.id === 'fern-footer') {
37+
if (observations < 3) {
38+
// react hydration will trigger a mutation event
39+
observations++
40+
} else {
41+
o.disconnect()
42+
}
43+
break
44+
}
45+
}
46+
}
47+
}).observe(document.body, { childList: true, subtree: true })
48+
})
49+
}

0 commit comments

Comments
 (0)