反应-如何在道具传递 HTML 标签?

我希望能够传递带有 HTML 标记的文本,如下所示:

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

但是在 MyComponent的渲染方法中,当我打印出 this.props.text时,它实际上打印出了所有东西:

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

有没有什么方法可以使 React 解析 HTML 并正确地将其转储出来?

188849 次浏览

您可以使用带有字符串和 JSX 元素的混合数组(参见文档 给你) :

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

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

此外,作为最后的手段,你总是有 插入原始 HTML 的能力,但要小心,因为这可以打开你的跨网站脚本(XSS)攻击,如果没有清理的属性值。

已经使用 jQuery append 将 html 添加到组件 DidMount 中,这应该可以解决这个问题。

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


return (
<div>


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

你可以使用 非常危险

只需将 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

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

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

您还可以使用组件上的函数将 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>
);
},


});

对我来说,它的工作原理是在道具孩子中传递 html 标签

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




var MyComponent = React.createClass({


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

在我的项目中,我必须从变量中传递动态 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>
);
}
});

普朗克的例子

危险的反应文档

你可以用我所知道的两种方法来做。

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

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

您希望在您的道具中使用 JSX

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

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

实现这一点的最佳可读方法是创建一个函数 renderMyProp,它将返回 JSX 组件(就像标准呈现函数一样) ,然后简单地调用 myProp = { this. renderMyProp ()}

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

默认情况下,JSX 不允许使用字符串值呈现原始 HTML。然而,有一种方法可以做到这一点:

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

然后在你的组件中你可以这样使用它:

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

注意,这个解决方案“可以”打开跨网站脚本伪造攻击。还要注意,您只能呈现简单的 HTML,没有 JSX 标记或组件或其他花哨的东西。

数组方式

作为反应,您可以传递一个 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 将可以在 Some Component 中作为 this. prop.children 使用,并且可以使用标准{}语法进行呈现。

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

但是,如果有多个内容,则不能使用子内容(或者至少需要将其与另一个解决方案组合在一起)

是的,可以通过使用带字符串和 JSX 元素的混合数组来实现

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

在 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

在客户端响应应用程序中,有几种方法可以使用一些 html 将道具呈现为字符串。一个比另一个安全..。

1-将道具定义为 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-危险设置内部 HTML

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

•不鼓励采用第二种方法。设想一个输入字段,其输入值在该组件中作为道具呈现。用户可以在输入中输入一个脚本标记,而呈现这个输入的组件将执行这个潜在的恶意代码。因此,这种方法有可能引入跨网站脚本漏洞。 要了解更多信息,请参考官方的 React 文档

@ matagus 的答案对我来说很好,希望下面的片段能帮助那些希望在里面使用变量的人。

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

来自 Html-response-parser 反应-解析器的解析器是一个很好的解决方案

  • 安装它与 npm 或纱线
  • 从“ html-response-Parser”导入 Parser;
  • 说:

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

    而且效果很好。

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

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

这个问题已经有了很多答案,但我在这方面做错了一些事情,我认为值得分享:

我有这样的东西:

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()} />

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

您可以成功地利用 反应碎片完成此任务。根据使用的 React 版本,可以使用简短语法: <>或完整标记: <React.Fragment>。如果您不想在 HTML 标记中包装整个字符串,那么这种方法尤其有效。

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

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

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

例子

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

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

现在你想把这个 HTML 发送到另一个组件中,这个组件的名字是 Parent 组件。

电话:-

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

使用儿童:-

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

这工作对我来说再合适不过了。

这里有一个解决方案,不使用 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/

可以使用 <></>片段在道具中传递 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

这样做:

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

然后作为道具通过:

<MyComponent Text={MyText} />

现在您可以在组件中使用它:

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

这对我有用

<MyComponent text={<>some text <strong>bold text</strong> and more.</>} />

同样,如果你想在这里传递变量,你可以这样试试

<MyComponent text={<>My name is {variableName}. <strong>Bold text</strong> normal text</>} />