Dom*_*nik 5 node.js reactjs server-side-rendering
I used to compile and insert JSX components via
<div key={ ID } dangerouslySetInnerHTML={ { __html: HTML } } />
Run Code Online (Sandbox Code Playgroud)
which wrapped my HTML into a <div>
:
<div>my html from the HTML object</div>
Run Code Online (Sandbox Code Playgroud)
Now react > 16.2.0 has support for Fragments and I wonder if I can use that somehow to avoid wrapping my HTML in a <div>
each time I get data from the back end.
Running
<Fragment key={ ID } dangerouslySetInnerHTML={ { __html: HTML } } />
Run Code Online (Sandbox Code Playgroud)
will throw a warning
Warning: Invalid prop `dangerouslySetInnerHTML` supplied to `React.Fragment`. React.Fragment can only have `key` and `children` props.
in React.Fragment
Run Code Online (Sandbox Code Playgroud)
Is this supported yet at all? Is there another way to solve this?
Created an issue in the react repo for it if you want to upvote it.
不可能:
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>'
)}
</>
Run Code Online (Sandbox Code Playgroud)
该问题(OP 也提到)已于 2019 年 10 月 2 日关闭。 - 然而,从最初的问题来看,RawHTML 组件似乎已进入RFC 流程,但尚未达到生产阶段,并且没有设定工作时间表。解决方案可能是可用的。
话虽这么说,我现在想提到我目前用来解决这个问题的解决方案。
就我而言,dangerouslySetInnerHTML
它被用来呈现简单的内容HTML
以供用户下载;在输出中包含额外的包装标签并不理想。
在阅读了网络和 StackOverflow 后,似乎大多数解决方案都提到了使用html-react-parser这样的外部库。
对于这个用例,html-react-parser是不够的,因为它将 HTML 字符串转换为React 元素。这意味着,它将删除所有非标准 JSX 的 HTML。
下面的代码是我选择使用的无库解决方案:
//HTML that will be set using dangerouslySetInnerHTML
const html = `<div>This is a div</div>`
Run Code Online (Sandbox Code Playgroud)
组件内的包装 divRawHtml
特意命名为“unwanteddiv”。
//Component that will return our dangerouslySetInnerHTML
//Note that we are using "unwanteddiv" as a wrapper
const RawHtml = () => {
return (
<unwanteddiv key={[]}
dangerouslySetInnerHTML={{
__html: html,
}}
/>
);
};
Run Code Online (Sandbox Code Playgroud)
出于本示例的目的,我们将使用renderToStaticMarkup。
const staticHtml = ReactDomServer.renderToStaticMarkup(
<RawHtml/>
);
Run Code Online (Sandbox Code Playgroud)
函数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;
}
};
Run Code Online (Sandbox Code Playgroud)
现在,如果我们传递staticHtml
该ParseStaticHtml
函数,您将看到所需的输出,而无需额外的包装器 div:
console.log(ParseStaticHtml(staticHtml));
Run Code Online (Sandbox Code Playgroud)
此外,我还创建了一个codesandbox 示例来展示这一点的实际效果。
请注意,控制台日志将抛出警告:“该标签<unwanteddiv>
在此浏览器中无法识别...” - 但是,这很好,因为我们故意给它一个唯一的名称,这样我们就可以使用我们的replace
方法轻松区分和定位包装器,本质上输出前将其删除。
此外,受到代码检查器的温和责骂并不像为应该更简单地实现的东西添加更多依赖项那么糟糕。
归档时间: |
|
查看次数: |
1958 次 |
最近记录: |