Skip to content
This repository has been archived by the owner on Jan 19, 2021. It is now read-only.

Commit

Permalink
Merge pull request #1 from aduth/master
Browse files Browse the repository at this point in the history
Assign and reuse element key by child index
  • Loading branch information
ellatrix authored May 10, 2017
2 parents e57605e + c91849c commit df50c97
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 2 deletions.
10 changes: 10 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,14 @@ export function attributeListToReact (attributeList) {
}, {})
}

let keyCounter = 0

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

const child = nodeToReact(node, createElement)

if (Array.isArray(child)) {
Expand Down Expand Up @@ -146,6 +152,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
36 changes: 34 additions & 2 deletions index.test.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { describe, it } from 'mocha'
import { equal } from 'assert'
import { equal, ok, deepEqual } from 'assert'
import { JSDOM } from 'jsdom'
import { createElement } from 'react'
import { renderToStaticMarkup } from 'react-dom/server'

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

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

describe('nodeListToReact', () => {
const rxKey = /^_domReact\d+$/
function assertKey (key) {
ok(rxKey.test(key), 'expected to match key pattern ' + rxKey.toString())
}

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)

assertKey(elements[0].key)
equal('string', typeof elements[0].props.children[0])
assertKey(elements[0].props.children[1].key)
assertKey(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
const before = nodeListToReact(list.childNodes, createElement)

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

const after = nodeListToReact(list.childNodes, createElement)
deepEqual(
before.map(({key}) => key),
after.map(({key}) => key).reverse()
)
})
})
})

0 comments on commit df50c97

Please sign in to comment.