如何在同一棵树中渲染子组件
How to render child component in the same tree
这可能是我的误解,但我有以下情况:
我有一个名为DaliBox的React组件,它具有一些智能(拖动、调整大小等),其中可能包含一些我未知的HTML,并使用__dangerouslySetInnerHTML分配给DaliBox。但是,如果HTML中有一个自定义标记(本例中为<plugin />
),那么我希望它承载一个新的React组件(PluginPlaceholder),该组件将充当DaliBox容器。
我所做的是,在ComponentDidMount内部,在DOMNode中找到<plugin />
标记,然后使用ReactDOM.render来渲染传入必要道具的PluginPlaceholder。问题是,当为Chrome使用React DevTools扩展时,我可以看到这会创建某种不同的"树",迫使我手动更新。
问题是,我做错了什么吗?这是唯一的方法吗?还是有可能在旧树中创建新的React树,让React发挥其魔力并自动更新?
提前非常感谢
您应该尽可能长时间地避免__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>
);
}
我不测试这个代码,它可能不会工作,但我希望你能理解这个想法,并能将其扩展到你的问题
根据您的描述,您的DOM树似乎有多个所有者/编辑器:
<body>
- 。。。其他HTML元素-->未由react管理
<DaliBox />
-->由react管理- 。。。其他HTML-->未由react管理
<div id='pluginplaceholder'>
-->不由react管理,但将用新的(递归)react<DaliBox>
替换- 。。。等等
这对于react来说并不理想(委婉地说)。感觉就像是在尝试对DOM结构中的随机级别应用react
这是jQuery允许并促进的,但它与react不太配合。
按最佳到最差的方式应用反应:
- 应用react的理想方法是让react完全垄断您的DOM结构的一部分,包括所有子体。然后您有一个react实例,管理DOM/HTML的特定(如果不是全部的话)
- 不太理想,但仍然是常见的做法:应用程序对DOM结构的多个不相关部分作出反应。通过具有多个反应实例(多个
ReactDOM.render()
) - 甚至不太理想,但如果绝对不可避免的话,可能是可以接受的:让react完全垄断DOM结构的1个(或多个)部分,但忽略最低级别。通过将CCD_ 12应用于这些最低水平
- 灾难的配方,要不惜一切代价避免:让react管理树中的DOM级别1-4,但不是级别5和6,另一个react实例管理DOM级别7及更低
在递归的情况下,我建议您坚持理想的情况:根本不使用_dangerouslySetInnerHTML()
。或者重新思考代码/行为/DOM中react适用的特定部分。(也许您不需要在DOM的拖放部分做出反应)。
这背后的原因是:react依赖于它自己的(隐藏的)DOM虚拟副本,并依赖于虚拟副本和DOM始终同步。如果其他一些代码开始扰乱react应该管理的DOM部分,那么您的虚拟DOM和真实DOM将不再同步,您的react代码将很快产生不可预测的结果,并且变得完全不可调试。
- 加载器组件仅加载一次
- 有没有一种方法可以使用任何浏览器扩展整个dom树'的开发工具
- ReacJS与猴面包树,如何在卸载组件后释放光标
- 如何在javascript中使用2个一维数组创建层次结构树
- 有没有一条清晰的路径,我可以实现一个在 ScalaJS + React 中广泛使用上下文的 React 组件
- 反应 - 树组件
- React Js 组件在状态更改后只渲染一次
- 如何在同一棵树中渲染子组件
- JsTree:如何在将节点从一棵树拖到第二棵树时获取事件
- 如何使用javascript在递归对象中找到基于一键的树级别
- 如何在reactjs中管理树组件中的状态
- c#mvc一次只允许一个用户编辑树视图
- 使用 broccoli-requirejs 从同一棵树构建两个不同的文件时出错
- 如何在 d3.js 中走一棵树
- 使用treemodel.js合并两棵树
- 渲染出一棵树
- 如何使活泼的手风琴看起来像一棵树
- JSTREE - 不同页面中的一棵树
- 我怎样才能递归和异步地构建一棵未知大小的树
- 当一棵树加载时,它正在窃取焦点