'How can I render a <template /> tag with react?

Sometimes you might need to render web-components from your react app.

Web-components often use a special <template> ... </template> tag. But if I try to render such markup with react like this:

render() {
  return (
    <template>
      <div>some content</div>
    </template>
  )
}

then my web-components don't work correctly.



Solution 1:[1]

I know that this question has already an answer, but there is another, I guess simpler solution to do that creating hoc (Higher Order Component).

Just create new "component" like this:

// hoc/Template.js
const template = props => props.children
export default template

and then you can use it in your project this way:

import './hoc/Template.js'

...

render() {
  return (
    <Template>
      {'<div>some content</div>'}
    </Template>
  )
}

Newer version of react has already build it such a component, so you can achieve same thing without creating component.

import { Fragment } from 'react'

...

render() {
  return (
    <Fragment>
      {'<div>some content</div>'}
    </Fragment>
  )
}

Solution 2:[2]

This is actually a bug in React! https://github.com/facebook/react/issues/19932

When the native browser parses the <template> tag, it appends all children to the template's content fragment, instead of adding them as children. So a template should never actually have any children.

However, if you programmatically build the DOM (the way react-dom does), then the template will have an empty content fragment, since all children are added as children. This is why web components will not behave properly with these templates.

Here's an example of the problem too: https://codesandbox.io/s/new-sun-8l62o?file=/src/App.tsx:1056-1118

The easiest workaround is to use dangerouslySetInnerHTML, like so:

<template dangerouslySetInnerHTML={{ __html: `
  <p> Some text </p>
` }} />

This is limited by the fact that you can only supply raw HTML (no custom React elements). However, since you're using the <template> tag in the first place, it seems highly unlikely that you'd also be using React within the template.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Scott Rippey