我正在创建一个小型博客网站。我想在那个网站上写帖子。对于前端部分,我正在使用reactJS == 0.16.7。我将博客文章作为HTML文档保留在AWS S3中,并将博客文章元数据保留在AWS DynamoDB中。当我进入网站时,react从DynamoDB中获取帖子的元数据,并基于此从S3(HTML)中获取适当的博客文章。现在,我想增加将GitHub要点嵌入到我的帖子中的可能性。
由于它们是JS脚本,因此我无法轻易将这些要点嵌入博客文章本身。我现在要做的是:
user
和gist id
作为参数并渲染要点,user
/ gist id
的Gist占位符user
和id
取自div占位符“ id”字段。例如gist.github.com/superuser/superid
应该呈现为HTML博客文章文件中定义的内容)这是示例帖子:
<h1> Hello from blogpost! </h1>
Blog posts goes on...
First gist
<div class="gist" id="user/gist_id1">
Blog posts goes on...
Second gist
<div class="gist" id="user/gist_id2">
...
现在在componentDidMount
中,我阅读了此博客文章并生成要点占位符列表(占位符的ID用于从github提取要点)。帖子的HTML存储在该data
变量中。
var el = document.createElement( 'html' );
el.innerHTML = "<html><head></head><body>" + data + "</body></html>";
gists = el.getElementsByClassName("gist");
for (var i = 0; i < gists.length; i++) {
gists_list.push(gists[i].id)
}
this.setState({content: {__html: data}, gists: gists_list});
渲染(在render函数中)时,我遍历此列表并尝试使用createPortal渲染要点
for (var i = 0; i < this.state.gists.length; i++) {
console.log("ID: " + this.state.gists[i])
gist_portals.push(
ReactDOM.createPortal(
<Gist gist={this.state.gists[i]} />,
document.getElementById(this.state.gists[i])
)
)
}
然后渲染它:
<div>
<p dangerouslySetInnerHTML={this.state.content} style={pStyle}></p>
{gist_portals}
</div>
document.getElementById(this.state.gists[i])
中引用的DOM元素应通过<p dangerouslySetInnerHTML={this.state.content} style={pStyle}></p>
保存到DOM(这将呈现博客文章的HTML)
不幸的是,我总是以错误的结尾:React Error: Target Container is not a DOM Element
当我使用预定义的DOM元素而不是博客文章文件中定义的DOM元素进行测试时,它可以工作。
我的假设是DOM元素不可用,因为我试图在尚未在DOM中的对象上创建门户。
如何使博客文章中的DOM元素可用于createPortal?