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

Axios请求后弹窗提示与按钮交互异常排查

书籍租赁校验代码异常问题

问题描述

我编写了一段用于校验书籍是否已租赁的代码,Axios请求功能正常,但存在以下问题:

  • 当书籍已租赁并完成支付后,点击「Show Book Rented」按钮时,会先弹出提示弹窗,再进入书籍页面;
  • 需要双击按钮才能进入书籍,似乎Axios请求后的setBookIsRent状态更新存在延迟,再次点击才会正常进入并显示正确的弹窗。

相关代码

校验函数代码

function rentChecker(){
    try{
      //Checking if the book is Rented
      axios.post('http://***********/getBooksRent',
      {
        userID : global.id,
        bookID : bookShow.id
      }).then((response) => { 
          const data = response.data;
          console.log(data[0])
          setBookIsRent(data);
      })

    
      var today = new Date().getTime()/1000;
      console.log(today);
        
      var bookRentTimeStamp = new Date(bookIsRent[0].TimeEnd).getTime()/1000;
      console.log(bookRentTimeStamp);

      var checker = (today > bookRentTimeStamp)
      console.log("Real time is greater than rent time ? Answer--> " + checker)

    
      if(bookIsRent[0].bookRented == 1 && (today < bookRentTimeStamp)){ 
        navigation.navigate('WebViewPdf',{paramKey:bookShow}) 
      }
      else if(checker){
        Alert.alert("Forbitten,book not Rented!")
      }
    }catch(error){
      Alert.alert("Forbitten,book not Rented!")
    }
  }

按钮组件代码

<Pressable style = {styles.pressableInsideModal} onPress = {() => { rentChecker() }}>
   <Text style = {styles.textInsideModal}>Show Book Rented</Text>
</Pressable>
问题排查与修复方案

核心问题分析

问题出在异步请求的执行顺序上:Axios发送POST请求是异步操作,你在发送请求后立刻就执行了时间校验、状态判断逻辑,这时候setBookIsRent还没完成状态更新,代码用的还是之前的旧状态值。所以第一次点击时,判断逻辑基于旧数据触发错误提示;第二次点击时,状态已经更新,才能得到正确的判断结果。

另外,React的状态更新本身也是异步的,即使调用了setBookIsRent,也无法在回调外立刻拿到新的状态值,这进一步加剧了问题。

修复代码

把所有依赖请求返回数据的逻辑,全部移到Axios的.then()回调内部,并且直接使用请求返回的data进行判断(不用依赖状态更新),修改后的代码如下:

function rentChecker(){
  axios.post('http://***********/getBooksRent',
  {
    userID : global.id,
    bookID : bookShow.id
  }).then((response) => { 
      const data = response.data;
      console.log(data[0])
      setBookIsRent(data);

      // 所有判断逻辑移到回调内,确保使用最新的请求数据
      const today = new Date().getTime()/1000;
      console.log(today);
        
      const bookRentTimeStamp = new Date(data[0].TimeEnd).getTime()/1000;
      console.log(bookRentTimeStamp);

      const checker = today > bookRentTimeStamp;
      console.log("Real time is greater than rent time ? Answer--> " + checker)

      if(data[0].bookRented === 1 && !checker){ 
        navigation.navigate('WebViewPdf',{paramKey:bookShow}) 
      } else if(checker){
        Alert.alert("Forbitten,book not Rented!")
      }
  }).catch(error => {
    // 捕获请求失败的情况
    Alert.alert("Forbitten,book not Rented!")
  })
}

额外优化点

  • 用const替代var,避免变量提升带来的潜在问题;
  • 将Axios请求的错误捕获移到.catch()中,更精准地处理请求失败场景;
  • 把today < bookRentTimeStamp改成!checker,逻辑更简洁一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 14:40:37