正确定义了Telegram Webapp的MainButton.onClick()



我正在尝试定义window.Telegram.WebApp.MainButton.onClick()功能以使用最新的值。

让我们看看代码:

// selectedRegions is an array of strings
const [selectedRegions, setSelectedRegions] = React.useState([""]);
React.useEffect(() => {
window.Telegram?.WebApp.MainButton.onClick(() => {
//   window.Telegram.WebApp.sendData(selectedRegions);
alert("main button clicked");
});
}, [selectedRegions]);

现在,当我更新selectedRegions时,这个useEffect被调用状态变化的次数,这也更新了MainButton.onClick()功能。然后在最后,当按下MainButton时,在这种情况下,alert()显示状态更新的次数,例如,如果selectedRegions包含3个值,则警报将显示3次。

我想要的是以某种方式定义这个onClick()一次或功能只执行一次,这样我就可以只发送一次selectedRegions和最近的值回bot。

更新1:在查看了telegram-web-app.js文件中的onEvent()函数后,

function onEvent(eventType, callback) {
if (eventHandlers[eventType] === undefined) {
eventHandlers[eventType] = [];
}
var index = eventHandlers[eventType].indexOf(callback);
if (index === -1) {
eventHandlers[eventType].push(callback);
}
};

在我看来,如果回调存在于eventHandlers["webView:mainButtonClicked"]中,那么它将不做任何事情,否则只是将其推入数组。我不明白的是,回调是不同的,这就是为什么他们被附加到数组,证明多次调用它。

然而,我试图使用MainButton.offClick()eventHandlers数组中删除,尚未成功。如果有人这样做了,我将不胜感激。

我也遇到过完全相同的问题。我有一些按钮更新状态,在主按钮点击我想发送状态,但你提到电报存储所有回调在数组中,当你调用sendData函数,web应用程序被关闭,只有第一个回调被执行。如果你试图用offClick删除函数,我认为那没有工作,因为回调是通过引用进行比较的,但是组件中的函数是在组件重新渲染时由react重新创建的,所以,这就是offClick未能删除该函数的原因。在这种情况下,解决方案是这样的

const sendDataToTelegram = () => {
window.Telegram.WebApp.sendData(selectedRegions);
}
useEffect(() => {
window.Telegram.WebApp.onEvent('mainButtonClicked', sendDataToTelegram)
return () => {
window.Telegram.WebApp.offEvent('mainButtonClicked', sendDataToTelegram)
}
}, [sendDataToTelegram])

如果你不熟悉这个语法——返回useEffect回调之前,被称为新useEffect又叫做

或者你也可以用useCallback钩子来解决这个问题,只有当选择的区域状态改变时才重新创建函数。这样的:

const sendDataToTelegram = useCallback(() => {
window.Telegram.WebApp.sendData(selectedRegions);
}, [selectedRegions])
useEffect(() => {
window.Telegram.WebApp.onEvent('mainButtonClicked', sendDataToTelegram)
return () => {
window.Telegram.WebApp.offEvent('mainButtonClicked', sendDataToTelegram)
}
}, [sendDataToTelegram])

我在typescript中使用Angular,我也遇到了这个问题。但我最终找到了一个解决方案:由于某种原因,如果我传递这样一个回调-";offClick(() => this.myFunc())";内部的indexof;offEvent"找不到此回调并返回"-1"。所以我最后写了:

setOnClick() {
let f = () => this.myFunc;
window.Telegram.WebApp.MainButton.onClick(f);
}
setOffClick() {
let f = () => this.myFunc;
window.Telegram.WebApp.MainButton.offClick(f);
}
myFunc() {
console.log('helloworld');
}

希望对你有帮助。

useEffect(() => {
if (isShow) {
Telegram.WebApp.MainButton.setText('');
Telegram.WebApp.MainButton.show();
Telegram.WebApp.MainButton.enable();
Telegram.WebApp.MainButton.onClick(setSelectedRegionsHandler);
}
return () => {
Telegram.WebApp.MainButton.hide();
Telegram.WebApp.MainButton.offClick(setSelectedRegionsHandler);
};
}, [isShow, setSelectedRegionsHandler]);

最新更新