【问题标题】:How to include Preact component with hooks in React app?如何在 React 应用程序中包含带有钩子的 Preact 组件?
【发布时间】:2020-03-28 21:14:03
【问题描述】:

这听起来可能不寻常,但我正在尝试在 React 应用程序中导入带有 Preact 钩子的 Preact 组件。不幸的是,这样做会引发Cannot read property '__H' of undefined。更多内容如下。

假设,为了简单起见,Preact 组件位于这样的包中:

// src/components/index.js
import { h } from 'preact';
import { useRef } from 'preact/hooks';

const PreactComponent = () => {
  const ref = useRef(null);
  return <div ref={ref}>Hello World</div>;
};

// package.json
{
  "name: "mypackage",
  "main": "dist/index.js", // Output by Webpack, with src/components/index.js as entrypoint.
  ...
}

标准的东西。它被导入到 React 应用程序中:

...
import { PreactComponent } from 'mypackage';

const MyComponent = () => {
  return <PreactComponent />
};

这会抛出Unhandled Rejection (TypeError): Cannot read property '__H' of undefined

肯定与 Preact 钩子相关,因为在 Preact 组件中删除 useRef 会导致组件渲染正常。正如您将在上面看到的,钩子是在函数内部定义的,应该是这样。

有没有人尝试在 React 中使用带有钩子的 Preact 组件?你是怎么做的?

【问题讨论】:

    标签: reactjs preact


    【解决方案1】:

    这是因为 React 渲染器不知道 Preact 特定的内部结构而引发的。如果我们检查 JSX 的转译输出,我们会得到:

    // Won't work, PreactComponent is not a React component
    React.createElement(PreactComponent, null)
    

    解决这个问题的最简单方法是提供一个可以渲染 Preact 的 DOM 节点。

    import React, { useRef, useEffect } from "react";
    import { render, h } from "preact";
    import { PreactComponent } from "./whatever";
    
    function ReactPreactBridge() {
      // Get the raw DOM node to render into
      const ref = useRef(null)
    
      useEffect(() => {
        if (ref.current) {
          // Can't use two different JSX constructors in
          // the same file, so we're writing the JSX output
          // manually. (h is the same as createElement)
          render(h(PreactComponent, null), ref.current)
        }
    
        return () => {
          // Clear Preact rendered tree when the parent React
          // component unmounts
          render(null, ref.current);
        }
      }, [ref.current]);
    
      return <div ref={ref} />
    }
    

    【讨论】:

      猜你喜欢
      • 2017-04-04
      • 2021-03-16
      • 1970-01-01
      • 2020-01-27
      • 2020-02-17
      • 1970-01-01
      • 2020-03-04
      • 2019-10-16
      相关资源
      最近更新 更多