admin管理员组文章数量:1390391
I am trying to define window.Telegram.WebApp.MainButton.onClick()
functionality to use the most recent values.
Lets see through code:
// 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]);
Now as I update the selectedRegions
, this useEffect
is called for the number of times the state changes which also updates the MainButton.onClick()
functionality. Then at the end, when the MainButton
is pressed, in this case, alert()
is shown the number of times the state was updated, eg, if the selectedRegions
contain 3 values, the alert will be shown 3 times.
What I want is to somehow define this onClick()
once or the functionality executed only once, so that I can send the selectedRegions
only once with the most recent values back to the bot.
UPDATE 1: After looking into the function onEvent()
in telegram-web-app.js file,
function onEvent(eventType, callback) {
if (eventHandlers[eventType] === undefined) {
eventHandlers[eventType] = [];
}
var index = eventHandlers[eventType].indexOf(callback);
if (index === -1) {
eventHandlers[eventType].push(callback);
}
};
It seems to my understanding that if the callback is present in eventHandlers["webView:mainButtonClicked"]
, then it will not do anything, otherwise just push it into the array.
What I fail to understand is that somehow the callbacks are different, that's why they get appended to the array, justifying the multiple calls to it.
However, I am trying to use MainButton.offClick()
to remove the from eventHandlers
array, have not succeeded yet. If anyone has done so, it would be highly appreciated.
I am trying to define window.Telegram.WebApp.MainButton.onClick()
functionality to use the most recent values.
Lets see through code:
// 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]);
Now as I update the selectedRegions
, this useEffect
is called for the number of times the state changes which also updates the MainButton.onClick()
functionality. Then at the end, when the MainButton
is pressed, in this case, alert()
is shown the number of times the state was updated, eg, if the selectedRegions
contain 3 values, the alert will be shown 3 times.
What I want is to somehow define this onClick()
once or the functionality executed only once, so that I can send the selectedRegions
only once with the most recent values back to the bot.
UPDATE 1: After looking into the function onEvent()
in telegram-web-app.js file,
function onEvent(eventType, callback) {
if (eventHandlers[eventType] === undefined) {
eventHandlers[eventType] = [];
}
var index = eventHandlers[eventType].indexOf(callback);
if (index === -1) {
eventHandlers[eventType].push(callback);
}
};
It seems to my understanding that if the callback is present in eventHandlers["webView:mainButtonClicked"]
, then it will not do anything, otherwise just push it into the array.
What I fail to understand is that somehow the callbacks are different, that's why they get appended to the array, justifying the multiple calls to it.
However, I am trying to use MainButton.offClick()
to remove the from eventHandlers
array, have not succeeded yet. If anyone has done so, it would be highly appreciated.
4 Answers
Reset to default 3I have faced exactly same issue. I had some buttons that updates state and on main button click I wanted to send that state, but as you mentioned telegram stores all callbacks in array and when you call sendData function, web app gets closed and only first callback is executed. If you tried to remove function with offClick, I think that didn't worked, because callbacks are pared by reference, but function in ponent was recreated by react when ponent is re-rendered, so, that's why offClick failed to remove that function. In this case solution would be like this
const sendDataToTelegram = () => {
window.Telegram.WebApp.sendData(selectedRegions);
}
useEffect(() => {
window.Telegram.WebApp.onEvent('mainButtonClicked', sendDataToTelegram)
return () => {
window.Telegram.WebApp.offEvent('mainButtonClicked', sendDataToTelegram)
}
}, [sendDataToTelegram])
If you are not familiar with this syntax - return in useEffect is callback that is called before new useEffect is called again
Or you can solve this also with useCallback hook to recreate function only when selected region state is changed. Like this:
const sendDataToTelegram = useCallback(() => {
window.Telegram.WebApp.sendData(selectedRegions);
}, [selectedRegions])
useEffect(() => {
window.Telegram.WebApp.onEvent('mainButtonClicked', sendDataToTelegram)
return () => {
window.Telegram.WebApp.offEvent('mainButtonClicked', sendDataToTelegram)
}
}, [sendDataToTelegram])
I use Angular with typescript and I ran into this problem too. But I finally found a solution: for some reason if I pass a callback like this -
"offClick(() => this.myFunc())
" the inner "indexOf" of the "offEvent" cannot find this callback and returns "-1".
So I ended up with:
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');
}
Hope this helps.
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]);
The easiest way - to copy telegram-web-app.js to your repository and rewrite function onEvent for WebView.
I rewrote it to this:
function onEvent(eventType, callback) {
eventHandlers[eventType] = [callback];
};
本文标签: javascriptDefining MainButtononClick() for Telegram Webapp correclyStack Overflow
版权声明:本文标题:javascript - Defining MainButton.onClick() for Telegram Webapp correcly - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744711172a2621138.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论