我希望能够使用HTML标记传递文本,如下所示:
<MyComponent text="This is <strong>not</strong> working." />
但是在MyComponent
的渲染方法中,当我打印出this.props.text
时,它会打印出所有内容:
This is <strong>not</strong> working.
有没有办法让React解析HTML并将其正确地转储出去?
答案 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元素相同:它必须只返回一个根元素。
myProp={<div><SomeComponent>Some String</div>}
最好的可读方法是创建一个函数renderMyProp,它将返回JSX组件(就像标准的render函数一样)然后只需调用myProp = {this.renderMyProp()}
默认情况下,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"]}
我不推荐这种方法,因为:
为了完整起见而添加它,但在做出反应时,您还可以让所有孩子都在组件的“内部”。
所以,如果我采用以下代码:
<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的字符串。一个比另一个更安全...
const someProps = {
greeting: {<div>Hello<a href="/${name_profile}">${name_profile}</a></div>}
}
const GreetingComopnent = props => (
<p>{props.someProps.greeting}</p>
)
•这里唯一的要求是,无论生成此道具的任何文件都需要包含React作为依赖项(以防在辅助文件中生成道具的jsx等)。
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>
}
/>
答案 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>
);
}
});
答案 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)
解析器是一个很好的解决方案。您只需要
用:
调用它<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的一种好方法,而不必很危险地
答案 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>
)
}}
/>
这应呈现为:
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);
}
});