如何使用react渲染<template>标记?

时间:2017-03-16 21:35:35

标签: reactjs web-component jsx documentfragment

有时您可能需要从您的反应应用中呈现网络组件。

Web组件通常使用特殊的<template> ... </template>标记。 但是,如果我尝试使用这样的反应来渲染这样的标记:

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

然后我的网络组件无法正常工作。

2 个答案:

答案 0 :(得分:7)

原因是JSX的作用与<template />标签的作用不同。模板标记的想法是不渲染其子项并且几乎像未解析的文本一样处理它(浏览器实际上只是解析它以确保其有效的html,但不做其他任何事情)

但是当你在JSX中写这个:

return (
  <template>
    <div>some content</div>
  </template>
)

您基本上是在指示创建'template'元素,然后创建'div'元素,然后将此div附加到{{1}作为一个孩子。

因此,发生了这种情况:

template

但你想要的是将const template = document.createElement('template') const div = document.createElement('div') const text = document.createTextNode('some text') div.appendChild(text) template.appendChild(div) 的内容设置为字符串。您可以使用<template />

解决方案

一种解决方案是:

innerHTML

现在你要求做出反应,将所有这些子标记创建为节点元素,但让浏览器决定如何处理它们。

更好的解决方案

您可能不想一直使用render() { return ( <template dangerouslySetInnerHTML={{ __html: '<div>some content</div>' }} /> ) } 。所以让我们创建一个辅助组件:

dangerouslySetInnerHTML

现在,只要您需要使用模板,就可以像这样使用它:

function Template({ children, ...attrs }) {
  return (
    <template
      {...attrs}
      dangerouslySetInnerHTML={{ __html: children }}
    />
  );
}

不要忘记将内部内容放在引号中,因为它应该是一个字符串。

答案 1 :(得分:0)

我知道这个问题已经有了答案,但我想还有另一个更简单的解决方案,即创建hoc(高阶组件)。

只需创建新的“组件”,如下所示:

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

然后您可以通过以下方式在项目中使用它:

import './hoc/Template.js'

...

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

较新版本的react已将其构建为此类组件,因此无需创建组件即可实现相同的目的。

import { Fragment } from 'react'

...

render() {
  return (
    <Fragment>
      {'<div>some content</div>'}
    </Fragment>
  )
}
相关问题