我想将现有的 React 组件包装在 StencilJS 组件中。
我通过在 StencilJScomponentDidRender钩子内调用 ReactDom.render并在渲染后将其移动到 react 子元素中来工作,但我想知道是否有更好的方法来实现这一点。
我不喜欢这需要宿主内部的两个包装器元素,并且手动将插槽移动到 React 组件中感觉非常讨厌。
示例代码 - 我在这里尝试渲染的现有 React 组件是来自 react-bootstrap 项目的 Bootstrap Alert,仅作为示例。
import {
Component,
ComponentInterface,
Host,
h,
Element,
Prop,
Event,
} from '@stencil/core';
import { Alert, AlertProps } from 'react-bootstrap';
import ReactDOM from 'react-dom';
import React from 'react';
@Component({
tag: 'my-alert',
styleUrl: 'my-alert.css',
shadow: false,
})
export class MyAlert implements ComponentInterface, AlertProps {
@Element() el: HTMLElement;
@Prop() bsPrefix?: string;
@Prop() variant?:
| 'primary'
| 'secondary'
| 'success'
| 'danger'
| 'warning'
| 'info'
| 'dark'
| 'light';
@Prop() dismissible?: boolean;
@Prop() show?: boolean;
@Event() onClose?: () => void;
@Prop() closeLabel?: string;
@Prop() transition?: React.ElementType;
componentDidRender() {
const wrapperEl = this.el.getElementsByClassName('alert-wrapper')[0];
const slotEl = this.el.getElementsByClassName('slot-wrapper')[0];
const alertProps: AlertProps = {
variant: this.variant,
dismissible: this.dismissible,
show: this.show,
onClose: this.onClose,
closeLabel: this.closeLabel,
transition: this.transition,
};
ReactDOM.render(
React.createElement(
Alert,
alertProps,
React.createElement('div', { className: 'tmp-react-child-el-class-probs-should-be-a-guid-or-something' })
),
wrapperEl
);
const reactChildEl = this.el.getElementsByClassName(
'tmp-react-child-el-class-probs-should-be-a-guid-or-something'
)[0];
reactChildEl.appendChild(slotEl);
}
render() {
return (
<Host>
<div class="alert-wrapper"></div>
<div class="slot-wrapper">
<slot />
</div>
</Host>
);
}
}