我如何 "bridge" 反应 DOM 差距

How can I "bridge" React DOM gap

我正在使用 Next.js 编写我的第一个 React 应用程序,但我遇到了困难。我的页面中有一张地图。地图是非常复杂的元素,我需要将反应组件插入其中。所以情况是:

<body>
  <SomeContext.Provider value={...}>
    <React>
      <Dom>
        <TheMap />
      </Dom>
    </React>
  </SomeContext.Provider>
</body>

地图只是一个包装元素,地图是使用 useRef() 渲染到其中的。但我需要在地图 DOM 中添加一些内容。该地图有一个 API 需要原生 HTMLElement。所以我做了类似的东西:

function mkElementWithComponent(someReactComponent) {
  const elm = document.createElement("div");
  ReactDOM.render(<someReactComponent />, elm);
  return elm;
}

这似乎有效,直到我发现以这种方式呈现的组件无法读取 SomeContext 值。它只读取默认值。这是个问题。如何解决这个问题?有没有办法弥补 React DOM 中的差距?我可以通过什么来让它工作?

改为创建一个 React 门户。签名和用法与 ReactDOM.render 几乎相同。该门户允许您在 DOM 中的其他地方呈现组件,但让它们的行为就像它们只是普通的子组件一样。

Portals

Usage

Normally, when you return an element from a component’s render method, it’s mounted into the DOM as a child of the nearest parent node:

render() {
  // React mounts a new div and renders the children into it
  return (
    <div>
      {this.props.children}
    </div>
  );
}

However, sometimes it’s useful to insert a child into a different location in the DOM:

render() {
  // React does *not* create a new div. It renders the children into `domNode`.
  // `domNode` is any valid DOM node, regardless of its location in the DOM.
  return ReactDOM.createPortal(
    this.props.children,
    domNode
  );
}

更新您的代码:

function mkElementWithComponent(someReactComponent) {
  const elm = document.createElement("div");
  ReactDOM.createPortal(<someReactComponent />, elm);
  return elm;
}