You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native中Onpress事件如何等待异步函数执行完成再运行后续逻辑

React Native按钮首次点击不生效异步问题解决方案

核心问题原因

  1. Firebase的get查询是异步操作,原noOpponent函数没有对外暴露异步完成的回调/Promise,调用后无法得知查询结束时机,后续判断逻辑会提前执行。
  2. React的状态更新为异步批量操作,就算setOpponent执行完成,当前渲染闭包内的opponent变量仍然是旧值,无法立即读取到更新后的结果。

修改步骤

1. 改造noOpponent函数,返回异步查询结果

把原本在函数内更新状态的逻辑拆分,让函数直接返回查询得到的布尔结果,方便外部调用时等待异步完成。

export const noOpponent = async (Key) => {
  console.log("key: " + Key)
  const querySnapshot = await duettsRef
    .where("key", "==", Key)
    .where("player1", "!=", firebase.auth().currentUser.uid)
    .where("player2", "==", "")
    .limit(1)
    .get()
  const hasOpponent = !querySnapshot.empty
  console.log("QuerysnapshotResult: " + hasOpponent)
  return hasOpponent
};

2. 改造按钮点击事件,用async/await等待异步结果

点击事件改为异步函数,等待查询结果返回后再执行后续的判断逻辑,同时新增加载状态防止重复点击。

const DuellScreen = () => {
  const [opponent, setOpponent] = useState(null);
  // 新增加载状态避免重复提交
  const [loading, setLoading] = useState(false);

  const handleApplyPress = async () => {
    if (loading) return;
    try {
      setLoading(true);
      // 等待Firebase查询完成拿到结果
      const hasOpponent = await noOpponent(code);
      // 可以保留状态更新供其他场景使用
      setOpponent(hasOpponent);
      console.log("OPPONENT:" + hasOpponent);
      
      // 直接用拿到的结果做逻辑判断
      if (hasOpponent) {
        setKeyToDuett(code);
        if (Platform.OS === "android") {
          ToastAndroid.show("Game joined!", ToastAndroid.SHORT);
        } else {
          Alert.alert("Game joined!");
        }
      } else {
        const msg = "Game does not exist or someone else has already joined!";
        if (Platform.OS === "android") {
          ToastAndroid.show(msg, ToastAndroid.SHORT);
        } else {
          Alert.alert(msg);
        }
      }
    } catch (err) {
      // 可自行补充网络异常、权限错误等场景的提示逻辑
      console.error("查询失败:", err);
    } finally {
      setLoading(false);
    }
  };

  return (
    ...
    <BlockButton
      text={loading ? "处理中..." : "Apply"}
      onPress={handleApplyPress}
      disabled={loading}
    />
    ...
  )
}

修改后点击按钮会等待Firebase查询完成再执行后续逻辑,首次点击即可拿到正确结果触发对应操作,无需二次点击。

内容的提问来源于stack exchange,提问作者Grrrrrag

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.20 10:45:04