【React】react-shadow原理(shadow-dom的探索)
前言突然对shadowdom感兴趣了,然后实现发现了很多坑,特此总结一下。实现原理函数组件我实现的有点bug,就是子组件的自己的状态无法改变,暂时不清楚为啥,如果有需要可以看一下react-shadow的实现:https://github.com/Wildhoney/ReactShadow/blob/master/src/core/index.js#L19类组件实现起来倒是没啥问题:export
·
前言
- 突然对shadowdom感兴趣了,然后实现发现了很多坑,特此总结一下。
实现原理
- 函数组件我实现的有点bug,就是子组件的自己的状态无法改变,暂时不清楚为啥,如果有需要可以看一下react-shadow的实现:https://github.com/Wildhoney/ReactShadow/blob/master/src/core/index.js#L19
- 类组件实现起来倒是没啥问题:
export class ShadowView extends React.Component {
state: {
root: null | ShadowRoot;
pdiv: null | HTMLDivElement;
div: null | HTMLDivElement;
} = {
root: null,
pdiv: null,
div: null,
};
setRoot = (pdiv: HTMLDivElement) => {
if (pdiv) {
const div = document.createElement("div");
const shadow = div.attachShadow({ mode: "open" });
pdiv.appendChild(div);
this.setState({ root: shadow, pdiv, div });
}
};
componentWillUnmount() {
if (this.state.pdiv && this.state.div) {
this.state.pdiv!.removeChild(this.state.div);
this.setState((pre) => ({ ...pre, root: null, div: null }));
}
}
render() {
const { children } = this.props;
const { root } = this.state;
return (
<div ref={this.setRoot}>
{root &&
ReactDOM.createPortal(children, root as unknown as Element)}
</div>
);
}
}
export function Axxx(props: { state: string; cl: Function }) {
const [state, setState] = useState(0);
return (
<div className="aaa">
xcsdsasdasdasdsad
{props.state}
{state}
<button
onClick={() => {
setState((pre) => pre + 1);
props.cl();
}}
>
++++
</button>
<button
onClick={() => {
setState((pre) => pre - 1);
props.cl();
}}
>
---
</button>
<a>xxx</a>
</div>
);
}
export class App extends React.Component {
state = { message: "..." };
onBtnClick = () => {
this.setState({ message: this.state.message + "xx" });
};
render() {
return (
<ShadowView>
<Axxx state={this.state.message} cl={this.onBtnClick}></Axxx>
</ShadowView>
);
}
}
export default App;
- 主要是必须有一个shadowRoot,所以在每次更新时,会出现卸载问题,然后重新去给已有的shadowRoot附上shadow导致报错。在卸载时删掉即可。
- 至于样式,需要那种服务端渲染的样式写法,或者内联样式,否则就是样式隔离。
- 目前正常来说除了样式比较麻烦,事件状态什么的是都有的,等我再用一段时间看看还有啥问题。
更多推荐
所有评论(0)