向 Lit React Wrapper 添加属性(使用 @lit/react)

问题描述 投票:0回答:1

好的,我需要在 React 应用程序中使用一个点亮的 Web 组件(使用 TS/TSX)。
(如果您认为这里的命名很奇怪,我使用的是虚拟名称)

我知道我可以像这样在 React 中使用 Web 组件:

<lit-web-component text="my text"></lit-web-component>

这样就可以了,它会显示组件。
然而,这个点亮的组件也会调度一个事件,我需要 React 应用程序来捕获这个事件。
经过研究,我发现我需要使用包(@lit/react)并创建一个包装组件来执行此操作。 (https://lit.dev/docs/frameworks/react/

我正在遵循文档,但我不断收到有关点亮组件(文本)上的属性的错误。它给出了这个错误:

Type '{ text: string; }' is not assignable to type 'IntrinsicAttributes & Omit<HTMLAttributes<HTMLElement>, never> & EventListeners<{}> & Partial<Omit<HTMLElement, keyof HTMLElement>> & RefAttributes<...>'.
  Property 'text' does not exist on type 'IntrinsicAttributes & Omit<HTMLAttributes<HTMLElement>, never> & EventListeners<{}> & Partial<Omit<HTMLElement, keyof HTMLElement>> & RefAttributes<...>

这是我正在创建的 React 包装组件:

export const MyElementComponent = createComponent({
  tagName: 'lit-web-component',
  elementClass: LitWebComponent,
  react: React,
  events: {
    onHeaderButtonClick: 'header-button-click',
  },
});

然后在react中使用它:

<MyElementComponent text="my text" />

它会产生上述错误。我不知道如何告诉它这个包装器需要接受这些属性。

LitWebComponent
正在导入为
import { LitWebComponent } from '@my-scope/my-lit-library';

如何声明这些属性?

我希望这个问题可以在 React 端解决,对 lit 组件进行更改会很困难。

reactjs web-component lit
1个回答
0
投票

我首先会说,如果它给您带来麻烦,您可能不需要在您的用例中使用

@lit/react
,并且您需要传入的 props 只是字符串。

您可以使用引用来强制添加事件侦听器。

const App = () => {
  const ref = useRef(null);
  
  useEffect(() => {
    if (ref.current) {
      const handler = (e) => { /* do stuff */ }
      ref.current.addEventListener('header-button-click', handler);
      return () => {
        ref.current.removeEventListener('header-button-click', handler);
      }
    }
  });

  return <lit-web-component ref={ref} text="my text"></lit-web-component>;
}

React 的未来版本(可能是 19) 将添加更好的自定义元素支持,以便您可以通过在事件名称前添加

on
并将其用作 prop 来添加事件侦听器。

如果您仍想使用

@lit/react
包装,

基于错误,似乎

createComponent
推断提供的
elementClass
的类型为
HTMLElement
,而它应该是扩展
HTMLElement
的类,
LitWebComponent
也应该具有
text
财产。

@lit/react
导出
ReactWebComponent
类型,您可以尝试使用它,就像

import {createComponent, type ReactWebComponent} from '@lit/react';

const _MyElementComponent = createComponent({
  tagName: 'lit-web-component',
  elementClass: LitWebComponent,
  react: React,
  events: {
    onHeaderButtonClick: 'header-button-click',
  },
});

export const MyElementComponent =
  _MyElementComponent as ReactWebComponent<
    LitWebComponent, {onHeaderButtonClick: 'header-button-click'}
  >;

虽然如果类型推断不起作用,我不确定这是否有效。

您还可以更直接地断言类型,例如

interface ElementProps {
  text: string;
  onHeaderButtonClick: (e: Event) => void;
}

export const MyElementComponent =
  _MyElementComponent as React.ForwardRefExoticComponent<
    React.PropsWithoutRef<ElementProps> & React.RefAttributes<LitWebComponent>
  >
© www.soinside.com 2019 - 2024. All rights reserved.