这可能是我的误解,但我有以下情况:
我有一个名为DaliBox的React组件,它具有一些智能(拖动,调整大小等),可能包含一些我不知道的HTML并使用__dangerouslySetInnerHTML分配给DaliBox。但是,如果在HTML内部有一个自定义标记(在这种情况下为<plugin />
),那么我希望它能够托管一个新的React组件(PluginPlaceholder),它将充当DaliBox容器。
我所做的是,在ComponentDidMount中,在DOMNNode中找到<plugin />
标签,然后使用ReactDOM.render渲染PluginPlaceholder传递必要的道具。问题是,当使用Chrome的React DevTools扩展时,我可以看到这会创建某种不同的“树”,迫使我手动更新。
问题是,我做错了吗?这是唯一的方法,还是可以在旧的React树中创建新的React树,让React做出自己的魔力并自动更新?
非常感谢您提前
答案 0 :(得分:0)
只要可能,您应该避免__dangerouslySetInnerHTML
。对于你的情况(如果我做对了)你不需要一个。
我们考虑<DaliBox />
和标记<div><p><PluginPlaceholder /></p></div>
。从你的问题我明白你有能力以某种方式解析这个标记。所以让我们考虑返回类似
parseMarkup
[
component: 'div',
children: [
component: 'p',
children: [
component: 'PluginPlaceholder'
]
]
]
不,你可以在没有任何魔法的情况下渲染你的树,例如:
renderChildren(markup) {
let component;
let children = [];
// get component. PluginPlaceholder or just string like 'div' or 'p'
switch (markup.component) {
case 'PluginPlaceholder':
component = PluginPlaceholder;
break;
default:
component = markup.component;
}
// recursively render children
if (markup.children) {
children = this.renderChildren(markup.children);
}
return React.createElement(component, [], children);
}
render() {
return (
<DaliBox>
{this.renderChildren(parseMarkup(this.props.markup))}
</DaliBox>
);
}
我没有测试这段代码,它可能无法正常工作,但我希望你能得到这个想法并为你的问题扩展它
答案 1 :(得分:0)
根据您的描述,您的DOM树看起来像有多个所有者/编辑者:
<body>
<DaliBox />
- &gt;由反应管理
<div id='pluginplaceholder'>
- &gt;不是由反应管理,而是用新的(递归的)反应<DaliBox>
替换
这不是理想的反应(温和地说)。感觉就像是在尝试对DOM结构中的随机级别应用反应 这是jQuery允许和促进的东西,但是反应并不顺利。
以最好的方式应用反应:
ReactDOM.render()
s)。_dangerouslySetInnerHTML()
应用于最低级别。在你的递归案例中,我建议坚持理想的情况:根本不使用_dangerouslySetInnerHTML()
。
或者重新考虑代码/行为/ DOM的特定部分,其中反应适用。 (也许你不需要在DOM的拖放部分做出反应)。
背后的原因:react依赖于它自己的(隐藏的)DOM 的虚拟副本,并依赖于虚拟副本和DOM始终保持同步。如果其他一些代码开始搞乱那些反应应该管理的DOM部分,那么你的虚拟DOM和真正的DOM就不再同步了,你的反应代码将很快产生不可预测的结果,并且变得完全不可判断。