React - 如何在道具中传递HTML标签?

ffx*_*sam 98 reactjs

我希望能够使用HTML标记传递文本,如下所示:

<MyComponent text="This is <strong>not</strong> working." />
Run Code Online (Sandbox Code Playgroud)

但是在MyComponent渲染方法中,当我打印出来时this.props.text,它会打印出所有内容:

This is <strong>not</strong> working.
Run Code Online (Sandbox Code Playgroud)

有没有办法让React解析HTML并将其正确地转储出去?

mat*_*gus 120

您可以将混合数组与字符串和JSX元素一起使用(请参阅此处的文档):

<MyComponent text={["This is ", <strong>not</strong>,  "working."]} />
Run Code Online (Sandbox Code Playgroud)

这里有一个小提琴,显示它有效:http://jsfiddle.net/7s7dee6L/

此外,作为最后的手段,您始终能够插入原始HTML,但要小心,因为如果不清理属性值,可能会导致跨站点脚本(XSS)攻击.

  • 这有效,除了我现在得到一个警告:警告:数组或迭代器中的每个子节点都应该有一个唯一的"键"支柱.检查CTA的render方法.它从Template1传递了一个孩子.有关更多信息,请参阅https://fb.me/react-warning-keys. (9认同)
  • 为了消除数组键警告,现在也可以像这样传递单个 JSX。`&lt;MyComponent text={&lt;&gt;这&lt;strong&gt;不&lt;/strong&gt;工作。&lt;/&gt;} /&gt;` (9认同)
  • 您还可以通过在`<strong>`元素上放置`key ="[some unique value]"`来修复警告. (4认同)
  • 您可以通过遍历数组并在MyComponent中添加索引作为键来消除此错误`{text.map(textOrHTML,index)=> <span key = {index}> {textOrHTML} </ span>)} "尽管如此,我们必须首先完全做到这一点. (3认同)

Atr*_*eur 93

实际上,有多种方法可以解决这个问题.

你想在你的道具中使用JSX

您可以简单地使用{}来使JSX解析参数.唯一的限制与每个JSX元素相同:它必须只返回一个根元素.

myProp={<div><SomeComponent>Some String</div>}
Run Code Online (Sandbox Code Playgroud)

最好的可读方法是创建一个函数renderMyProp,它将返回JSX组件(就像标准的render函数一样)然后只需调用myProp = {this.renderMyProp()}

您希望仅将HTML作为字符串传递

默认情况下,JSX不允许您从字符串值中呈现原始HTML.但是,有一种方法可以做到这一点:

myProp="<div>This is some html</div>"
Run Code Online (Sandbox Code Playgroud)

然后在您的组件中,您可以像这样使用它:

<div dangerouslySetInnerHTML=myProp={{ __html: this.renderMyProp() }}></div>
Run Code Online (Sandbox Code Playgroud)

请注意,此解决方案"可以"打开跨站点脚本伪造攻击.还要注意,您只能渲染简单的HTML,没有JSX标记或组件或其他奇特的东西.

阵列方式

在react中,您可以传递一组JSX元素.这意味着:

myProp={["This is html", <span>Some other</span>, "and again some other"]}
Run Code Online (Sandbox Code Playgroud)

我不推荐这种方法,因为:

  • 它会创建一个警告(缺少键)
  • 它不可读
  • 它不是真正的JSX方式,它更像是一个黑客而不是预期的设计.

孩子们的方式

添加它是为了完整性,但在做出反应时,您还可以获得所有组件内部的子项.

所以,如果我采取以下代码:

<SomeComponent>
    <div>Some content</div>
    <div>Some content</div>
</SomeComponent>
Run Code Online (Sandbox Code Playgroud)

然后这两个div将在SomeComponent中以this.props.children的形式提供,并且可以使用标准{}语法进行渲染.

当你只有一个HTML内容传递给你的组件时,这个解决方案是完美的(想象一下Popin组件只接受Popin的内容作为子组件).

但是,如果您有多个内容,则不能使用子项(或者您至少需要将其与其他解决方案结合使用)

  • 这是一个更好的答案,应该被选为这样的答案。 (2认同)

OSM*_*ote 19

您可以使用<></>Fragment 在 props 中传递 HTML。

<MyComponent text={<>"This is <strong>not</strong> working."</>} />
Run Code Online (Sandbox Code Playgroud)

参考: https: //reactjs.org/blog/2017/11/28/react-v16.2.0-fragment-support.html#jsx-fragment-syntax

  • 非常适合我。不需要双引号,只要您不想在屏幕上呈现它们即可: &lt;MyComponent text={&lt;&gt;This is &lt;strong&gt;not&lt;/strong&gt;working.&lt;/&gt;} /&gt; (2认同)

Ryn*_*oRn 14

从 React v16.02 开始,您可以使用 Fragment。

<MyComponent text={<Fragment>This is an <strong>HTML</strong> string.</Fragment>} />
Run Code Online (Sandbox Code Playgroud)

更多信息:https : //reactjs.org/blog/2017/11/28/react-v16.2.0-fragment-support.html

  • 这仅适用于您定义内联的 HTML,对吗?您不能执行“&lt;&gt;{myHtml}&lt;/&gt;”或类似的操作吗? (4认同)

hec*_*aso 10

您可以使用dangerouslySetInnerHTML

只需将html作为普通字符串发送即可

<MyComponent text="This is <strong>not</strong> working." />
Run Code Online (Sandbox Code Playgroud)

并在JSX代码中呈现如下:

<h2 className="header-title-right wow fadeInRight"
    dangerouslySetInnerHTML={{__html: props.text}} />
Run Code Online (Sandbox Code Playgroud)

如果要渲染用户输入的数据,请务必小心.您可能成为XSS攻击的受害者

这是文档:https: //facebook.github.io/react/tips/dangerously-set-inner-html.html


Sha*_*643 6

对我而言,它通过在道具儿童中传递html标签来实现

<MyComponent>This is <strong>not</strong> working.</MyComponent>


var MyComponent = React.createClass({

   render: function() {
    return (
      <div>this.props.children</div>
    );
   },
Run Code Online (Sandbox Code Playgroud)


Vij*_*Ram 6

在客户端反应应用程序中,有几种方法可以将prop作为带有一些html的字符串呈现.一个比另一个更安全......

1 - 将道具定义为jsx(我的偏好)

const someProps = {
  greeting: {<div>Hello<a href="/${name_profile}">${name_profile}</a></div>}
}


const GreetingComopnent = props => (
  <p>{props.someProps.greeting}</p>
)
Run Code Online (Sandbox Code Playgroud)

•这里唯一的要求是生成此prop的任何文件都需要包含React作为依赖项(如果您在辅助文件中生成prop的jsx等).

2 - 危险地设置innerHtml

const someProps = {
  greeting: '<React.Fragment>Hello<a href="/${name_profile}">${name_profile}</a></React.Fragment>'
}

const GreetingComponent = props => {
  const innerHtml = { __html: props.someProps.greeting }
  return <p dangerouslySetInnerHtml={innerHtml}></p>
}
Run Code Online (Sandbox Code Playgroud)

•不鼓励使用第二种方法.想象一个输入字段,其输入值在此组件中呈现为prop.用户可以在输入中输入脚本标记,并且呈现此输入的组件将执行此潜在的恶意代码.因此,此方法可能会引入跨站点脚本漏洞.有关更多信息,请参阅官方React文档


Ame*_*kar 6

将文本道具类型设置为any并执行以下操作:

<MyComponent text={
    <React.Fragment>
        <div> Hello, World!</div>
    </React.Fragment>
    } 
/>
Run Code Online (Sandbox Code Playgroud)

例子


小智 5

<MyComponent text={<span>This is <strong>not</strong> working.</span>} />
Run Code Online (Sandbox Code Playgroud)

然后在你的组件中你可以像这样进行道具检查:

import React from 'react';
export default class MyComponent extends React.Component {
  static get propTypes() {
    return {
      text: React.PropTypes.object, // if you always want react components
      text: React.PropTypes.any, // if you want both text or react components
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

确保您只选择一种道具类型.