2

这可能有点棘手 - 我想在通过 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>
    );
  }
}
4

1 回答 1

2

您可以使用@Element()domContainer装饰器并使用它来查询shadowRoot. 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 而不是代码更相关。

希望这会有所帮助!

于 2019-06-20T01:52:58.677 回答