在 Stencil Web 组件中进行 React 渲染

Posted

技术标签:

【中文标题】在 Stencil Web 组件中进行 React 渲染【英文标题】:React render inside Stencil Web Component 【发布时间】:2019-09-09 06:34:29 【问题描述】:

这可能有点棘手 - 我想在通过 Stencil 准备的 Web 组件中渲染 React,但我得到“不变违规:目标容器不是 DOM 元素。”:

import  Component, Prop  from "@stencil/core";
import  format  from "../../utils/utils";
import ReactDOM from 'react-dom';
import React from "react";
import  LikeButton  from './../LikeButton';

const e = React.createElement;

@Component(
  tag: "my-component",
  styleUrl: "my-component.css",
  shadow: true
)
export class MyComponent 
  @Prop() first: string;
  @Prop() middle: string;
  @Prop() last: string;

  private getText(): string 
    return format(this.first, this.middle, this.last);
  

  componentWillLoad() 
    console.log("here i am - the React render");
    const domContainer = document.querySelector("#like_button_container");
    ReactDOM.render(e(LikeButton), domContainer);
  

  render() 
    return (
      <div>
        Hello, World! I'm this.getText()" "
        <div id="like_button_container">React container</div>
      </div>
    );
  

【问题讨论】:

Invariant Violation: _registerComponent(...): Target container is not a DOM element的可能重复 【参考方案1】:

您可以使用@Element() 装饰器并使用它来查询shadowRoot 下的domContainer 元素。在这种情况下,shadowRoot 需要 @Element(),因为您将 shadow 设置为 true

import  Component, Element, Prop  from "@stencil/core";
import  format  from "../../utils/utils";
import ReactDOM from 'react-dom';
import React from "react";
import  LikeButton  from './../LikeButton';

const e = React.createElement;

@Component(
  tag: "my-component",
  styleUrl: "my-component.css",
  shadow: true
)
export class MyComponent 
  @Element() el: htmlElement;
  @Prop() first: string;
  @Prop() middle: string;
  @Prop() last: string;

  private getText(): string 
    return format(this.first, this.middle, this.last);
  

  componentWillLoad() 
    const domContainer = this.el.shadowRoot.querySelector("#like_button_container");
    ReactDOM.render(e(LikeButton), domContainer);
  

  render() 
    return (
      <div>
        Hello, World! I'm this.getText()" "
        <div id="like_button_container">React container</div>
      </div>
    );
  

在 stenciljs 开发模式下运行时,我遇到了间歇性问题。刷新页面时,我遇到的问题可能是由于缓存,但如果我通过保存包含此代码的 stenciljs 组件文件来触发重新加载,它通常可以工作。这可能与 stencil-dev-server 而不是代码有关。

希望对您有所帮助!

【讨论】:

以上是关于在 Stencil Web 组件中进行 React 渲染的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Storybook React App 中嵌入 StencilJS 组件?

如何从 Vue 实例外部触发 Stencil 组件功能/方法

Font Awesome 在 Stenciljs 组件中不起作用

每个网页都有DOM和body元素吗?

如何将图像插入 Web 组件?

stenciljs 学习七 路由