esxjs / esx

Like JSX, but native and fast
MIT License
652 stars 11 forks source link

`Warning: Each child in a list should have a unique "key" prop` with Text interleaved nodes #15

Open lmammino opened 4 years ago

lmammino commented 4 years ago

First of all, thanks a lot for the incredible work on this library. I love the idea of not having to transpile only because of JSX and, of course, the performance boost makes it even better.

Warning:

Warning: Each child in a list should have a unique "key" prop.
[1]
Check the top-level render call using <footer>. See https://fb.me/react-warning-keys for more information.
    in a
    in Footer
    in div
    in AuthorsIndex
    in Context.Provider
    in Context.Consumer
    in Route
    in Context.Consumer
    in Switch
    in App
    in Context.Provider
    in Router
    in StaticRouter

I am getting the warning above with the following code:

import react from 'react'
import esx from 'esx'

const e = esx()

export class Footer extends react.Component {
  render () {
    return e`
      <footer>
        Made with ♥ by <a target="_blank" href="x">@x</a>
        for <a target="_blank" href="y">Y</a>
      </footer>
    `
  }
}

e.register({ Footer })

The same warning does not appear with the equivalent React (createElement) code:

import react from 'react'

const h = react.createElement

export class Footer extends react.Component {
  render () {
    return (
      h('footer', null,
        'Made with ♥ by ',
        h('a', { target: '_blank', href: 'x' }, '@x'),
        ' for ',
        h('a', { target: '_blank', href: 'y' }, 'y')
      )
    )
  }
}

I am not sure what's the default React behaviour, but I suspect that this will be interpreted as the following DOM structure:

footer
├── textNode
├── a
└── textNode

And possibly React automatically generates a key for every children element in this case.

If my assumption is correct, Is this behaviour something that makes sense to implement in esx as well to avoid the warning? I also suspect this might have performance implications at runtime if the vDOM has to reconcile a transition with a big blob of text with anchors and other interleaved elements.

For the sake of completeness this is the demo project I am testing esx with: univ.

lmammino commented 4 years ago

I forgot to mention that this warning appears only on the server-side (reactServer.renderToString). It does not happen in the client (reactDOM.render)