阴影 DOM 和 ReactJS
Shadow DOM and ReactJS
我在我的应用程序中使用网络组件。在 Web 组件中,我需要插入一个 React 组件。 Web 组件有阴影 DOM。当我尝试使用以下方法渲染反应组件时出现错误。
comp = React.createElement(ReactElem, {
config: config,
onRender: handleRender
});
ReactDOM.render(comp , self.shadowRoot.querySelector('#app1'));
错误
target container is not a dom element
我尝试使用 Web 组件 API 的 content
,但随后它呈现在顶部而不是组件内部。任何线索如何使 React 组件在阴影中呈现 DOM?
如果您想将它插入网络组件的阴影 DOM 中,首先 select 组件(例如使用 querySelector
),然后是其包含的阴影(shadowRoot
).简化示例:
// Create React Element.
class Example extends React.Component {
onClick() {
console.log('Shadow!')
}
render() {
return(
<div onClick={this.onClick}>Hello World!</div>
);
}
}
// Create web component with target div inside it.
const container = document.createElement('app');
document.body.appendChild(container);
// Add shadow root to component.
const shadow = document.querySelector('app').attachShadow({ mode: 'open' });
// Select the web component, then the shadowRoot.
const target = document.querySelector('app').shadowRoot;
ReactDOM.render(<Example />, target);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
嘿我的朋友,我花时间为我们制作了这个:
// ShadowRoot.js
import React from "react";
export class ShadowRoot extends React.Component {
attachShadow(host) {
if (host == null) {
return;
}
host.attachShadow({mode: "open"});
host.shadowRoot.innerHTML = host.innerHTML;
host.innerHTML = "";
}
render() {
return (
<span ref={this.attachShadow}>
{this.props.children}
</span>
);
}
}
这样使用:
<ShadowRoot>
// put stuff here you want inside shadow root
</ShadowRoot>
2 个需要考虑的事项:
- class
React.Component
比挂钩等价物工作得更好
innerHTML
有点老套,状态更新不适用于此组件
看起来这个答案有点过时了,要将 Web 组件附加到 React 应用程序,您需要先将您的 Web 组件转换为模块。您可以通过使用类似 $) npm publish --access public
将其推送到 NPM 来完成此操作
这会将您的 Web 组件发布为 public NPM 模块,可以使用 npm install 下载 web-components-name-here。
现在您的代码已在构建时合并。您还需要采取一个步骤,那就是将其添加到您的根反应文件或 inxex.js--
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import { defineCustomElements } from 'your-custom--web-components/loader/index.js';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
defineCustomElements(window)
最后一段代码是将 npm 模块中的所有 Web 组件添加到 Reactjs 的全局范围的地方。现在您可以继续使用--
import React from 'react';
import './ReactFakeComp.css';
import ReactFakeComp from './App';
export default ReactFakeComp() {
render(
<your-custom--web-components />
);
}
您应用中的任何位置,就像常规 HTML 组件一样。
最后一件事,如果您是构建 npm 模块和发布它们的新手,我不想让这最后一部分劝阻您。我发现了一个叫做 Stencil 的工具,这是一个强大的工具,可以让你在一个隔离的环境中构建 Web 组件。它会自动创建所有其他额外的数据和文件,您需要使用导入以 CommonJS 或更新的 ES^ 语法发布您的 Web 组件。
但最重要的功能是您现在可以在 Typescript 中构建您的 Web 组件。我直接说没有更多的模板。 Stencil 将为您转换和构建一切。
我在我的应用程序中使用网络组件。在 Web 组件中,我需要插入一个 React 组件。 Web 组件有阴影 DOM。当我尝试使用以下方法渲染反应组件时出现错误。
comp = React.createElement(ReactElem, {
config: config,
onRender: handleRender
});
ReactDOM.render(comp , self.shadowRoot.querySelector('#app1'));
错误
target container is not a dom element
我尝试使用 Web 组件 API 的 content
,但随后它呈现在顶部而不是组件内部。任何线索如何使 React 组件在阴影中呈现 DOM?
如果您想将它插入网络组件的阴影 DOM 中,首先 select 组件(例如使用 querySelector
),然后是其包含的阴影(shadowRoot
).简化示例:
// Create React Element.
class Example extends React.Component {
onClick() {
console.log('Shadow!')
}
render() {
return(
<div onClick={this.onClick}>Hello World!</div>
);
}
}
// Create web component with target div inside it.
const container = document.createElement('app');
document.body.appendChild(container);
// Add shadow root to component.
const shadow = document.querySelector('app').attachShadow({ mode: 'open' });
// Select the web component, then the shadowRoot.
const target = document.querySelector('app').shadowRoot;
ReactDOM.render(<Example />, target);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
嘿我的朋友,我花时间为我们制作了这个:
// ShadowRoot.js
import React from "react";
export class ShadowRoot extends React.Component {
attachShadow(host) {
if (host == null) {
return;
}
host.attachShadow({mode: "open"});
host.shadowRoot.innerHTML = host.innerHTML;
host.innerHTML = "";
}
render() {
return (
<span ref={this.attachShadow}>
{this.props.children}
</span>
);
}
}
这样使用:
<ShadowRoot>
// put stuff here you want inside shadow root
</ShadowRoot>
2 个需要考虑的事项:
- class
React.Component
比挂钩等价物工作得更好 innerHTML
有点老套,状态更新不适用于此组件
看起来这个答案有点过时了,要将 Web 组件附加到 React 应用程序,您需要先将您的 Web 组件转换为模块。您可以通过使用类似 $) npm publish --access public
将其推送到 NPM 来完成此操作这会将您的 Web 组件发布为 public NPM 模块,可以使用 npm install 下载 web-components-name-here。
现在您的代码已在构建时合并。您还需要采取一个步骤,那就是将其添加到您的根反应文件或 inxex.js--
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import { defineCustomElements } from 'your-custom--web-components/loader/index.js';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
defineCustomElements(window)
最后一段代码是将 npm 模块中的所有 Web 组件添加到 Reactjs 的全局范围的地方。现在您可以继续使用--
import React from 'react';
import './ReactFakeComp.css';
import ReactFakeComp from './App';
export default ReactFakeComp() {
render(
<your-custom--web-components />
);
}
您应用中的任何位置,就像常规 HTML 组件一样。
最后一件事,如果您是构建 npm 模块和发布它们的新手,我不想让这最后一部分劝阻您。我发现了一个叫做 Stencil 的工具,这是一个强大的工具,可以让你在一个隔离的环境中构建 Web 组件。它会自动创建所有其他额外的数据和文件,您需要使用导入以 CommonJS 或更新的 ES^ 语法发布您的 Web 组件。
但最重要的功能是您现在可以在 Typescript 中构建您的 Web 组件。我直接说没有更多的模板。 Stencil 将为您转换和构建一切。