在 React 中是否有对应于 Angular "slots" 的 DOM 节点?
Is there a counterpart to Angular "slots" for DOM nodes in React?
目标是 create a W3C web component in React 支持任意 DOM 节点作为子节点。
浏览器中的初始标记应该是这样的:
<custom-button>
some <u>styled</u> text here
</custom-button>
然后我会:
- 调用
customElements.define()
将我的 React 代码注册为 custom-button
、 的实现
- 在实现内部创建影子根
<custom-button>
,
- 之后调用
ReactDOM.render(<CustomButton ...>, shadowRoot);
来填充这个影子根
浏览器中的 DOM 结构现在是:
<custom-button>
#shadow-root
<div class="CustomButton">
<!-- x -->
</div>
some <u>styled</u> text here
</custom-button>
但这并不是真正想要的结果;我现在需要 <custom-button>
的原始内容在 <div class="CustomButton">
中渲染。
我知道 React children
道具,但据我所知,它只适用于也在 React 实现中声明的子节点,而不适用于任意 DOM 节点在周围的 Web 组件元素上创建。
另一方面,我读到 Angular 实现了一个他们称为 "transclusion" 的概念,其中他们提供 slots
将映射到 DOM 个子 Web 组件。 React 中有类似的东西吗?
我在 React 中能想到的一个快速 "workaround" 是:
- 获取顶级JSX标签的
ref
,
- 在
ref.parentNode
中找到影子根
- 遍历所有子项并将它们作为新父项重新附加到
ref
虽然这只会涵盖初始化。如果在运行时,某些其他脚本试图将更多子项附加到 <custom-button>
,或者重新排序或删除以前插入的子项,这可能会失败。
我刚刚意识到 web components 标准的 <slot />
解决了这个问题。
所以,要在React组件内部反映<custom-element>
的内容,下面的内容就完全够了:
render() {
return (
<div className="customElement">
...
<slot />
...
</div>
);
}
目标是 create a W3C web component in React 支持任意 DOM 节点作为子节点。
浏览器中的初始标记应该是这样的:
<custom-button>
some <u>styled</u> text here
</custom-button>
然后我会:
- 调用
customElements.define()
将我的 React 代码注册为custom-button
、 的实现
- 在实现内部创建影子根
<custom-button>
, - 之后调用
ReactDOM.render(<CustomButton ...>, shadowRoot);
来填充这个影子根
浏览器中的 DOM 结构现在是:
<custom-button>
#shadow-root
<div class="CustomButton">
<!-- x -->
</div>
some <u>styled</u> text here
</custom-button>
但这并不是真正想要的结果;我现在需要 <custom-button>
的原始内容在 <div class="CustomButton">
中渲染。
我知道 React children
道具,但据我所知,它只适用于也在 React 实现中声明的子节点,而不适用于任意 DOM 节点在周围的 Web 组件元素上创建。
另一方面,我读到 Angular 实现了一个他们称为 "transclusion" 的概念,其中他们提供 slots
将映射到 DOM 个子 Web 组件。 React 中有类似的东西吗?
我在 React 中能想到的一个快速 "workaround" 是:
- 获取顶级JSX标签的
ref
, - 在
ref.parentNode
中找到影子根
- 遍历所有子项并将它们作为新父项重新附加到
ref
虽然这只会涵盖初始化。如果在运行时,某些其他脚本试图将更多子项附加到 <custom-button>
,或者重新排序或删除以前插入的子项,这可能会失败。
我刚刚意识到 web components 标准的 <slot />
解决了这个问题。
所以,要在React组件内部反映<custom-element>
的内容,下面的内容就完全够了:
render() {
return (
<div className="customElement">
...
<slot />
...
</div>
);
}