Skip to content
This repository was archived by the owner on Jan 19, 2021. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Assign and reuse element key by child index
  • Loading branch information
aduth committed May 5, 2017
commit cc3d1989c7d3f4747088ce14a10eb666e0dacdd3
10 changes: 9 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,11 @@ export function attributeListToReact (attributeList) {
}

export function nodeListToReact (nodeList, createElement) {
return [...nodeList].reduce((accumulator, node) => {
return [...nodeList].reduce((accumulator, node, index) => {
if (!node._domReactKey) {
node._domReactKey = String(index)
}

const child = nodeToReact(node, createElement)

if (Array.isArray(child)) {
Expand Down Expand Up @@ -146,6 +150,10 @@ export function nodeToReact (node, createElement) {
props = attributeListToReact(node.attributes)
}

if (node._domReactKey) {
props.key = node._domReactKey
}

if (node.hasChildNodes()) {
children = nodeListToReact(node.childNodes, createElement)
}
Expand Down
27 changes: 26 additions & 1 deletion index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { JSDOM } from 'jsdom'
import { createElement } from 'react'
import { renderToStaticMarkup } from 'react-dom/server'

import { nodeToReact } from './index'
import { nodeListToReact, nodeToReact } from './index'

const { window } = new JSDOM()
const { document } = window
Expand Down Expand Up @@ -95,4 +95,29 @@ describe('nodeToReact()', () => {
}
})))
})

describe('nodeListToReact', () => {
it('should return array of React element with key assigned by child index', () => {
document.body.innerHTML = '<p>test <span>test</span></p><strong>test</strong>'
const elements = nodeListToReact(document.body.childNodes, createElement)

equal('0', elements[0].key)
equal('string', typeof elements[0].props.children[0])
equal('1', elements[0].props.children[1].key)
equal('1', elements[1].key)
})

it('should reuse assigned key for same elements reference', () => {
document.body.innerHTML = '<ul><li>one</li><li>two</li></ul>'
const list = document.body.firstChild
let elements = nodeListToReact(list.childNodes, createElement)

// Rearrange second list item before first
list.insertBefore(list.lastChild, list.firstChild)

elements = nodeListToReact(list.childNodes, createElement)
equal('1', elements[0].key)
equal('0', elements[1].key)
})
})
})