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

i2loujxw  于 2023-05-16  发布在  Java
关注(0)|答案(3)|浏览(105)

我正在尝试定义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()一次,或者只执行一次的功能,这样我就可以只向bot发送一次selectedRegions和最新的值。
更新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数组中删除,尚未成功。如果有人这样做了,我们将不胜感激。

dwbf0jvd

dwbf0jvd1#

我也遇到过同样的问题。我有一些更新状态的按钮,点击主按钮时我想发送状态,但正如你提到的电报将所有回调存储在数组中,当你调用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中的return是在再次调用new 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])
tjjdgumg

tjjdgumg2#

我使用Angular和typescript,我也遇到了这个问题。但我终于找到了解决办法:由于某种原因,如果我传递一个回调函数,比如“offClick(() => this.myFunc())”,“offEvent”的内部“indexOf”就找不到这个回调函数,并返回“-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');
}

希望这能帮上忙。

wb1gzix0

wb1gzix03#

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]);

相关问题