0
0
mirror of https://github.com/honojs/hono.git synced 2024-11-21 18:18:57 +01:00

fix(jsx/dom): fix dom rendering bugs for fragment. (#3569)

This commit is contained in:
Taku Amano 2024-10-30 11:11:55 +09:00 committed by GitHub
parent ea3d799cdf
commit 3164326351
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 54 additions and 9 deletions

View File

@ -1119,6 +1119,46 @@ describe('DOM', () => {
)
})
it('consecutive fragment', async () => {
const ComponentA = () => {
const [count, setCount] = useState(0)
return (
<>
<div>A: {count}</div>
<button id='a-button' onClick={() => setCount(count + 1)}>
A: +
</button>
</>
)
}
const App = () => {
const [count, setCount] = useState(0)
return (
<>
<ComponentA />
<div>B: {count}</div>
<button id='b-button' onClick={() => setCount(count + 1)}>
B: +
</button>
</>
)
}
render(<App />, root)
expect(root.innerHTML).toBe(
'<div>A: 0</div><button id="a-button">A: +</button><div>B: 0</div><button id="b-button">B: +</button>'
)
root.querySelector<HTMLButtonElement>('#b-button')?.click()
await Promise.resolve()
expect(root.innerHTML).toBe(
'<div>A: 0</div><button id="a-button">A: +</button><div>B: 1</div><button id="b-button">B: +</button>'
)
root.querySelector<HTMLButtonElement>('#a-button')?.click()
await Promise.resolve()
expect(root.innerHTML).toBe(
'<div>A: 1</div><button id="a-button">A: +</button><div>B: 1</div><button id="b-button">B: +</button>'
)
})
it('switch child component', async () => {
const Even = () => <p>Even</p>
const Odd = () => <div>Odd</div>

View File

@ -368,17 +368,22 @@ const applyNodeObject = (node: NodeObject, container: Container, isNew: boolean)
const childNodes = (isNew ? undefined : container.childNodes) as NodeListOf<ChildNode>
let offset: number
let insertBeforeNode: ChildNode | null = null
if (isNew) {
offset = -1
} else if (!childNodes.length) {
offset = 0
} else {
const offsetByNextNode = findChildNodeIndex(childNodes, findInsertBefore(node.nN))
if (offsetByNextNode !== undefined) {
insertBeforeNode = childNodes[offsetByNextNode]
offset = offsetByNextNode
} else {
offset =
(childNodes.length &&
(findChildNodeIndex(childNodes, findInsertBefore(node.nN)) ??
findChildNodeIndex(
childNodes,
next.find((n) => n.tag !== HONO_PORTAL_ELEMENT && n.e)?.e
))) ??
findChildNodeIndex(childNodes, next.find((n) => n.tag !== HONO_PORTAL_ELEMENT && n.e)?.e) ??
-1
}
if (offset === -1) {
isNew = true
}
@ -418,7 +423,7 @@ const applyNodeObject = (node: NodeObject, container: Container, isNew: boolean)
// Move extra elements to the back of the container. This is to be done efficiently when elements are swapped.
container.appendChild(childNodes[offset])
} else {
container.insertBefore(el, childNodes[offset] || null)
container.insertBefore(el, insertBeforeNode || childNodes[offset] || null)
}
}
}