在后台从 React 组件制作 HTML 字符串,如何在另一个 React 组件中通过危险的SetInnerHTML 使用该字符串
Posted
技术标签:
【中文标题】在后台从 React 组件制作 HTML 字符串,如何在另一个 React 组件中通过危险的SetInnerHTML 使用该字符串【英文标题】:Making an HTML string from a React component in background, how to use the string by dangerouslySetInnerHTML in another React component 【发布时间】:2017-09-19 21:49:46 【问题描述】:我正在尝试在 React 项目中渲染 LaTeX 字符串。
虽然我使用react-mathjax
React 组件,但我想获得一个由 LaTeX 字符串组成的 html 字符串,以便将它和其他字符串连接起来,并通过 dangerouslySetInnerHTML 设置它。
我尝试过的当前代码
示例代码在这里:https://github.com/Nyoho/test-react-project/blob/component2string/src/components/tex.jsx
-
LaTeX 字符串以字符串形式给出
document.createElement('span')
创建一个空的 DOM aDom
(在后台。不在文档 DOM 树中。)
将ReactDOM.render
的LaTeX字符串渲染成aDom
渲染后通过aDom.innerHTML
或.outerHTML
获取字符串
问题
aDom.innerHTML
(或.outerHTML
)的值为"<span><span data-reactroot=\"\"></span></span>"
(几乎为空)
尽管aDom
有一个由 MathJax 生成的完美树。
简单地说,
aDom
: ????
aDom.outerHTML
: ????
A screenshot console.log of aDom
and aDom.outerHTML
问题
如何从上面的aDom
获取“正确”的 HTML 字符串?
【问题讨论】:
【参考方案1】:据我所知,你得到了你期望得到的。
给定一个根元素(在您的情况下为aDom
),ReactDOM 将在该元素内呈现它的根组件,并且该组件的元素将具有data-reactroot
属性。
所以你所看到的正是它应该的样子。根据我的测试,内部 dom 树也应该在那里。
var Another = React.createClass(
render: function()
return (
<div>Just to see if other components are rendered as well</div>
);
);
var Hello = React.createClass(
render: function()
return (
<div id="first">
<div id="sec-1">Hello</div>
<div id="sec-2"> this.props.name </div>
<Another />
</div>
);
);
var a = document.createElement('div');
ReactDOM.render(
<Hello name = "World" /> ,
a
);
console.log(a.outerHTML);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
控制台中的结果是:
<div><div data-reactroot="" id="first"><div id="sec-1">Hello</div><div id="sec-2">World</div><div>Just to see if other components are rendered as well</div></div></div>
【讨论】:
哎呀,我得到了我期望得到的东西!那么,问题可能是react-mathjax
?
console.log(c)
在componentToString
函数的开头会得到什么?
将console.log(c)
插入componentToString
函数的第1行,我得到了imgur.com/6Q9sjNm(它似乎是一个React元素。)
我从您在问题中发布的屏幕截图中看到,MathJax 在 DOM 中插入了一个脚本标签,该标签可能会在相应的跨度中呈现输出。我相信这就是您在渲染到内存时发现跨度为空的原因。如果您确实需要这样做,您可以在真实 DOM (display: none
) 中创建一个不可见的 div 并在此处渲染您的组件。您应该在那里获得完整的内容。
我想我只是不明白......你上面的示例代码和我的 MathJax 案例有什么区别?为什么你的案例不需要在页面的真实 DOM 中制作一个不可见的 div?【参考方案2】:
如果您想将任何组件呈现为 HTML 字符串,这似乎工作得很好:
import renderToString from 'react-dom/server'
renderToString()
return renderToString(<MyAwesomeComponent some="props" or="whatever" />)
【讨论】:
太棒了!谢谢! (抱歉来晚了。)我在 renderToString 分支中用renderToString
重写了它:github.com/NyohoSampleCodes/test-react-project/blob/… 但它似乎仍然是空的。
缺少function
吗?也许换个名字,重用导入的名字会让人困惑。
喜欢它!对于需要 html 字符串的属性来说太有用了。现在创建一个组件,然后将其字符串化为 html。美丽:)【参考方案3】:
我建议使用 renderToStaticMarkup
而不是 renderToString
,因为它不会添加任何额外的 React 内部使用的 DOM 属性,例如 `data-reactroot:
import renderToStaticMarkup from 'react-dom/server'
getString()
return renderToStaticMarkup(<AnyComponent />)
文档:
【讨论】:
以上是关于在后台从 React 组件制作 HTML 字符串,如何在另一个 React 组件中通过危险的SetInnerHTML 使用该字符串的主要内容,如果未能解决你的问题,请参考以下文章