英文:
Adding functions to lit web components in react with typescript
问题
我创建了一个在lit中制作的Web组件,它接受一个函数作为输入属性,但该函数未能从React组件中触发。
import React, { FC } from 'react';
import '@webcomponents/widgets';
declare global {
namespace JSX {
interface IntrinsicElements {
'webcomponents-widgets': WidgetProps
}
}
}
interface WidgetProps extends React.DetailedHTMLProps<React.HTMLAttributes
var1: string,
successCallback: Function,
}
const App = () => {
const onSuccessCallback = () => {
console.log("在此添加一些逻辑");
}
return(
}
如何在React组件中触发该函数?我在Vue 3中尝试了这个,结果如预期。
我漏掉了什么吗?
英文:
I have a web component i created in lit, which takes in a function as input prop. but the function is not being triggered from the react component.
import React, { FC } from 'react';
import '@webcomponents/widgets'
declare global {
namespace JSX {
interface IntrinsicElements {
'webcomponents-widgets': WidgetProps
}
}
}
interface WidgetProps extends React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement> {
var1: string,
successCallback: Function,
}
const App = () =>{
const onSuccessCallback = () =>{
console.log("add some logic here");
}
return(<webcomponents-widgets var1="test" successCallBack={onSuccessCallback}></webcomponents-widgets>)
}
How can i trigger the function in react component? I have tried this is vue 3 and is working as expected.
Am i missing something?
答案1
得分: 2
如在此答案中指出,React 目前不正确地处理 Web 组件的函数属性。
虽然可以使用 ref 来以命令方式添加函数属性,但我建议在 Web 组件中更符合惯例的做法是不将函数作为属性传递,而是让 Web 组件在“成功”时分派事件,然后由使用者编写事件处理程序。
因此,<webcomponents-widgets>
的实现,而不是调用
this.successCallBack();
可以改为
const event = new Event('success', {bubbles: true, composed: true});
this.dispatchEvent(event);
然后,在您的 React 组件中,您可以添加事件侦听器。
const App = () => {
const widgetRef = useRef();
const onSuccessCallback = () => {
console.log("在此添加一些逻辑");
}
useEffect(() => {
widgetRef.current?.addEventListener('success', onSuccessCallback);
return () => {
widgetRef.current?.removeEventListener('success', onSuccessCallback);
}
}, []);
return(<webcomponents-widgets var1="test" ref={widgetRef}></webcomponents-widgets>);
}
@lit-labs/react
包允许您包装 Web 组件,将其转换为 React 组件,以便以声明方式处理此类事件。
英文:
As pointed out in this answer, React does not handle function props for web components properly at this time.
While it's possible to use a ref to add the function property imperatively, I would suggest the more idiomatic way of doing things in web components is to not take a function as a prop but rather have the web component dispatch an event on "success" and the consumer to write an event handler.
So the implementation of <webcomponents-widgets>
, instead of calling
this.successCallBack();
would instead do
const event = new Event('success', {bubbles: true, composed: true});
this.dispatch(event);
Then, in your React component you can add the event listener.
const App = () => {
const widgetRef = useRef();
const onSuccessCallback = () => {
console.log("add some logic here");
}
useEffect(() => {
widgetRef.current?.addEventListener('success', onSuccessCallback);
return () => {
widgetRef.current?.removeEventListener('success', onSuccessCallback);
}
}, []);
return(<webcomponents-widgets var1="test" ref={widgetRef}></webcomponents-widgets>);
}
The @lit-labs/react
package let's you wrap the web component, turning it into a React component so you can do this kind of event handling declaratively.
答案2
得分: 1
React 对 Web 组件的处理不如其他框架那么好(但计划在将来改进)。
这里发生的情况是,您的 successCallBack
参数被转换为字符串。您需要在 Web 组件上设置一个引用,并从 useEffect
中设置 successCallBack
:
const App = () => {
const widgetRef = useRef();
const onSuccessCallback = () =>{
console.log("在这里添加一些逻辑");
}
useEffect(() => {
if (widgetRef.current) {
widgetRef.current.successCallBack = onSuccessCallback;
}
}, []);
return(<webcomponents-widgets var1="test" ref={widgetRef}></webcomponents-widgets>)
}
英文:
React does not handle Web Components as well as other frameworks (but it is planned to be improved in the future).
What is happening here is that your successCallBack
parameter gets converted to a string. You need to setup a ref on your web component and set successCallBack
from a useEffect
:
const App = () => {
const widgetRef = useRef();
const onSuccessCallback = () =>{
console.log("add some logic here");
}
useEffect(() => {
if (widgetRef.current) {
widgetRef.current.successCallBack = onSuccessCallback;
}
}, []);
return(<webcomponents-widgets var1="test" ref={widgetRef}></webcomponents-widgets>)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论