我曾经通过
编译和插入JSX组件<div key={ ID } dangerouslySetInnerHTML={ { __html: HTML } } />
将我的HTML包装成<div>
:
<div>my html from the HTML object</div>
现在react > 16.2.0 has support for Fragments我想知道是否可以以某种方式使用它来避免每次从后端获取数据时将我的HTML包装在<div>
中。
正在运行
<Fragment key={ ID } dangerouslySetInnerHTML={ { __html: HTML } } />
会发出警告
Warning: Invalid prop `dangerouslySetInnerHTML` supplied to `React.Fragment`. React.Fragment can only have `key` and `children` props.
in React.Fragment
这支持了吗?还有另一种解决方法吗?
如果您想要支持它,请为其创建一个issue in the react repo。
答案 0 :(得分:3)
不可能:
key是唯一可以传递给Fragment的属性。在里面 未来,我们可能会添加对其他属性的支持,例如事件 处理程序。
https://reactjs.org/docs/fragments.html
您可能想要加入并建议将其作为未来的补充。
https://github.com/facebook/react/issues
您可能需要考虑使用HTML解析库,如:
https://github.com/remarkablemark/html-react-parser
查看此示例,了解它将如何实现您的目标:
http://remarkablemark.org/blog/2016/10/07/dangerously-set-innerhtml-alternative/
你能够做到这一点:
<>
{require('html-react-parser')(
'<em>foo</em>'
)}
</>
答案 1 :(得分:2)
This issue(OP也提到)已于2019年10月2日关闭。-但是,从原始问题来看,似乎RawHTML component已经进入RFC process,但没有达到生产,并且没有确定何时可以使用有效解决方案的时间表。
话虽如此,我现在想提及我目前用于解决此问题的解决方案。
在我的情况下,dangerouslySetInnerHTML
用于呈现纯HTML
供用户下载;在输出中包含其他包装标签并不理想。
在浏览了网络和StackOverflow之后,似乎大多数解决方案都使用了html-react-parser之类的外部库。
在此用例中, html-react-parser 不够用,因为它将HTML字符串转换为React element(s)。意思是,它将删除所有非标准JSX的HTML。
下面的代码是我选择使用的无库解决方案:
//HTML that will be set using dangerouslySetInnerHTML
const html = `<div>This is a div</div>`
RawHtml
组件中的包装div特意命名为“ unwanteddiv”。
//Component that will return our dangerouslySetInnerHTML
//Note that we are using "unwanteddiv" as a wrapper
const RawHtml = () => {
return (
<unwanteddiv key={[]}
dangerouslySetInnerHTML={{
__html: html,
}}
/>
);
};
在此示例中,我们将使用renderToStaticMarkup。
const staticHtml = ReactDomServer.renderToStaticMarkup(
<RawHtml/>
);
神奇的地方是ParseStaticHtml
函数,在这里您将了解为什么我们将包装div命名为“ unwanteddiv”。
//The ParseStaticHtml function will check the staticHtml
//If the staticHtml type is 'string'
//We will remove "<unwanteddiv/>" leaving us with only the desired output
const ParseStaticHtml = (html) => {
if (typeof html === 'string') {
return html.replace(/<unwanteddiv>/g, '').replace(/<\/unwanteddiv>/g, '');
} else {
return html;
}
};
现在,如果我们通过staticHtml
函数传递ParseStaticHtml
,您将看到所需的输出,而无需附加包装div:
console.log(ParseStaticHtml(staticHtml));
此外,我还创建了一个codesandbox example来演示此操作。
注意,控制台日志将发出警告: “此浏览器无法识别标记<unwanteddiv>
...” -很好因为我们有意为它指定了唯一的名称,所以我们可以使用replace
方法轻松区分和定位包装器,并在输出之前将其删除。
此外,从代码棉签中受到轻度的责骂还不如为应该更简单实现的东西增加更多的依赖关系。