Как включить компонент Preact с хуками в приложении React? - PullRequest
0 голосов
/ 29 марта 2020

Звучит, возможно, необычно, но я пытаюсь импортировать компонент Preact с перехватчиками Preact в приложении React. К сожалению, при этом выдается 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 связаны , так как удаление useRef в компоненте Preact приводит к штрафу за рендеринг компонента. И, как вы увидите выше, ловушка определена внутри функции, как и должно быть.

Кто-нибудь пытался использовать компонент Preact с ловушками в React? Как вы go об этом?

1 Ответ

0 голосов
/ 02 апреля 2020

Это происходит из-за того, что средство визуализации React не знает о спецификациях Preact-* c. Если мы проверим транспонированный вывод JSX, мы получим следующее:

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

Самый простой способ решить эту проблему - предоставить DOM-узел, в который Preact может выполнять рендеринг.

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} />
}
...