好的,我需要在 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 组件进行更改会很困难。
我首先会说,如果它给您带来麻烦,您可能不需要在您的用例中使用
@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>
>