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

时间:2015-10-28 00:45:17

标签: reactjs

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

<MyComponent text="This is <strong>not</strong> working." />

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

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

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

23 个答案:

答案 0 :(得分:110)

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

<MyComponent text={["This is ", <strong>not</strong>,  "working."]} />

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

此外,作为最后的手段,您始终拥有the ability to insert raw HTML,但要小心,因为如果不对资产值进行清理,可能会导致跨站点脚本(XSS)攻击。

答案 1 :(得分:70)

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

你想在你的道具

中使用JSX

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

myProp={<div><SomeComponent>Some String</div>}

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

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

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

myProp="<div>This is some html</div>"

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

<div dangerouslySetInnerHTML=myProp={{ __html: this.renderMyProp() }}></div>

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

阵列方式

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

myProp={["This is html", <span>Some other</span>, "and again some other"]}

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

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

孩子们的方式

为了完整起见而添加它,但在做出反应时,您还可以让所有孩子都在组件的“内部”。

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

<SomeComponent>
    <div>Some content</div>
    <div>Some content</div>
</SomeComponent>

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

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

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

答案 2 :(得分:9)

您可以使用 dangerouslySetInnerHTML

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

<MyComponent text="This is <strong>not</strong> working." />

在JSX代码中渲染,如下所示:

<h2 className="header-title-right wow fadeInRight"
    dangerouslySetInnerHTML={{__html: props.text}} />

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

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

答案 3 :(得分:6)

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

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


var MyComponent = React.createClass({

   render: function() {
    return (
      <div>this.props.children</div>
    );
   },

答案 4 :(得分:6)

在客户端React应用程序上,有两种方法可以将prop呈现为带有某些html的字符串。一个比另一个更安全...

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

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


const GreetingComopnent = props => (
  <p>{props.someProps.greeting}</p>
)

•这里唯一的要求是,无论生成此道具的任何文件都需要包含React作为依赖项(以防在辅助文件中生成道具的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>
}

•不建议使用第二种方法。想象一下一个输入字段,其输入值在该组件中呈现为prop。用户可以在输入中输入脚本标签,而呈现此输入的组件将执行此潜在的恶意代码。因此,这种方法有可能引入跨站点脚本漏洞。 有关更多信息,请refer to the official React docs

答案 5 :(得分:5)

<MyComponent text={<span>This is <strong>not</strong> working.</span>} />

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

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
    }
  }
}

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

答案 6 :(得分:4)

将文本道具类型设置为任何,然后执行以下操作:

<MyComponent text={
    <React.Fragment>
        <div> Hello, World!</div>
    </React.Fragment>
    } 
/>

Example

答案 7 :(得分:4)

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

<MyComponent text={<Fragment>This is an <strong>HTML</strong> string.</Fragment>} />

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

答案 8 :(得分:3)

你可以通过我所知道的两种方式来做到这一点。

1- <MyComponent text={<p>This is <strong>not</strong> working.</p>} />

然后这样做

class MyComponent extends React.Component {
   render () {
     return (<div>{this.props.text}</div>)
   }
}

或者第二种做法就是这样做

2- <MyComponent><p>This is <strong>not</strong> working.</p><MyComponent/>

然后这样做

class MyComponent extends React.Component {
   render () {
     return (<div>{this.props.children}</div>)
   }
}

答案 9 :(得分:2)

您可以使用 <></> 片段在道具中传递 HTML。

<MyComponent text={<>"This is <strong>not</strong> working."</>} />

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

答案 10 :(得分:1)

这样做:

const MyText = () => {
     return (
          <>
               This is <strong>Now</strong> working.
          </>
     )
}

然后将其作为道具传递为:

<MyComponent Text={MyText} />

现在你可以在你的组件中使用它:

const MyComponent = ({Text}) => {
     return (
          <>
               // your code
               {<Text />}
               // some more code
          </>
     )
 }

答案 11 :(得分:1)

您可以成功利用React fragments来完成此任务。根据您使用的React版本,您可以使用短语法:<>或完整标签:<React.Fragment>。如果您不想将整个字符串都包装在HTML标签中,则效果特别好。

<MyComponent text={<>Hello World. <u>Don't be so ruthless</u>.</>} />

答案 12 :(得分:1)

这个问题已经有了很多答案,但是我做错了与此相关的事情,我认为值得分享:

我有这样的东西:

export default function Features() {
  return (
    <Section message={<p>This is <strong>working</strong>.</p>} />
  }
}

但是按摩的时间比那更长,所以我尝试使用这样的东西:

const message = () => <p>This longer message is <strong>not</strong> working.</p>;

export default function Features() {
  return (
    <Section message={message} />
  }
}

我花了一段时间才意识到我在函数调用中缺少()。

不起作用

<Section message={message} />

工作

<Section message={message()} />

也许对您有帮助,就像对我一样!

答案 13 :(得分:1)

在我的项目中,我必须从变量传递动态html片段并在组件内部渲染它。所以我做了以下事情。

defaultSelection : {
    innerHtml: {__html: '<strong>some text</strong>'}
}

defaultSelection 对象从.js文件

传递到组件
<HtmlSnippet innerHtml={defaultSelection.innerHtml} />

HtmlSnippet 组件

var HtmlSnippet = React.createClass({
  render: function() {
    return (
      <span dangerouslySetInnerHTML={this.props.innerHtml}></span>
    );
  }
});

enter image description here

Plunkr example

答案 14 :(得分:1)

您还可以使用组件上的函数将jsx传递给props。像:

 var MyComponent = React.createClass({

   render: function() {
    return (
      <OtherComponent
        body={this.body}
      />
    );
   },

   body() {
     return(
       <p>This is <strong>now</strong> working.<p>
     );
   }

});

var OtherComponent = React.createClass({

  propTypes: {
    body: React.PropTypes.func
  },

  render: function() {
     return (
        <section>
          {this.props.body()}
        </section>
     );
  },

});

答案 15 :(得分:0)

@matagus的答案对我来说很好,摘录下的希望对那些希望在内部使用变量的人有所帮助。

const myVar = 'not';
<MyComponent text={["This is ", <strong>{`${myVar}`}</strong>,  "working."]} />

答案 16 :(得分:0)

来自html-react-parser

解析器是一个很好的解决方案。您只需要

  • 用npm或yarn安装它
  • 从“ html-react-parser”导入解析器;
  • 用:

    调用它
    <MyComponent text=Parser("This is <strong>not</strong> working.") />
    

    效果很好。

答案 17 :(得分:0)

添加到答案:如果您打算解析,并且已经在JSX中,但是有一个带有嵌套属性的对象,那么一种非常优雅的方法是使用括号来强制JSX解析:

const TestPage = () => (
  <Fragment>
    <MyComponent property={
    {
      html: (
        <p>This is a <a href='#'>test</a> text!</p>
      )
    }}>
    </MyComponent>
  </Fragment>
);

答案 18 :(得分:0)

有没有人没有建议react-html-parser的原因吗?似乎是处理导入的HTML的一种好方法,而不必很危险地

https://www.npmjs.com/package/react-html-parser

答案 19 :(得分:0)

是的,您可以使用带有字符串和JSX元素的mix数组。 reference

<div class="ui fixed inverted main menu">
  <a (click)="toggle()" class="launch icon item">
    <i class="content icon"></i>
    <p style="padding-left:1em">Menu</p>
  </a>
</div>

答案 20 :(得分:0)

我们可以用这种方式做同样的事情。

const Child = () => {
  return (
     write your whole HTML here.
  )
}

现在您要在另一个名为Parent组件的组件中发送此HTML。

正在致电:-

<Parent child={<child/>} >
</Parent> 

使用儿童:-

 const Parent = (props) => {
   const { child } = props; 
   return (
       {child}
    )
}

这项工作对我来说很完美。

答案 21 :(得分:0)

这是一种不使用dangerouslySetInnerHTML的解决方案,正如名称所说,这很危险。

import { IntlProvider, FormattedMessage } from "react-intl";

<FormattedMessage
          id="app.greeting"
          description="Bold text example"
          defaultMessage="Look here, I can include HTML tags in plain string and render them as HTML: <b>Bold</b>, <i>Italics</i> and <a>links too</a>."
          values={{
            b: (chunks) => <b>{chunks}</b>,
            i: (chunks) => <i>{chunks}</i>,
            a: (chunks) => (
              <a class="external_link" target="_blank" href="https://jiga.dev/">
                {chunks}
              </a>
            )
          }}
        />

这应呈现为:

react jiga.dev

https://jiga.dev/react-render-string-with-html-tags-from-props/

中的完整示例

答案 22 :(得分:-8)

使用jQuery append在componentDidMount中附加了html。这应该可以解决问题。

 var MyComponent = React.createClass({
    render: function() {

        return (
           <div>

           </div>
        );
    },
    componentDidMount() {
        $(ReactDOM.findDOMNode(this)).append(this.props.text);
    }
});