在我对独立应用程序 expo-deeplink 进行测试后,调度功能似乎运行了不止一次

Posted

技术标签:

【中文标题】在我对独立应用程序 expo-deeplink 进行测试后,调度功能似乎运行了不止一次【英文标题】:Dispatch function seems to run more than one time after I test on stand alone app expo-deeplink 【发布时间】:2021-04-21 23:46:22 【问题描述】:

这对我来说听起来很奇怪,我不知道这里出了什么问题,因为在开发环境中一切都很好。所以应用程序的工作方式很简单,用户登录,选择它的治疗师然后付款,成功付款后,预订确认,但问题是预订在 firebase 实时数据库中被预订了 3 次,无论如何,我不知道为什么......(在开发区一切都很好,它会按照用户的要求只预订一次)

这是我的预订代码:

const bookingHandler = () => 
    Linking.openURL('http://www.medicalbookingapp.cloudsite.ir/sendPay.php');
  

  const handler = (e) => handleOpenUrl(e.url);
  useEffect(() => 

    Linking.addEventListener('url', handler)

    return () => 
      Linking.removeEventListener('url', handler);

    

  );

  const handleOpenUrl = useCallback((url) => 
    const route = url.replace(/.*?:\/\/\w*:\w*\/\W/g, '') // exp://.... --> ''
    const id = route.split('=')[1]

    if (id == 1) 
      handleDispatch();
      toggleModal();
     else if (id == 0) 
      console.log('purchase failed...');
      toggleModal();
    
  );

  const handleDispatch = useCallback(() => 
    dispatch(
      BookingActions.addBooking(
        therapistId,
        therapistFirstName,
        therapistLastName,
        selected.title,
        moment(selectedDate).format("YYYY-MMM-DD"),
        selected.slots,
      )
    );

    dispatch(
      doctorActions.updateTherapists(therapistId, selected.slots, selectedDate, selected.title, selectedPlanIndex, selectedTimeIndex)
    );
    setBookingConfirm(true)
  )

预订操作:

export const addBooking = (therapistId, therapistFirstName, therapistLastName, sessionTime, sessionDate, slotTaken) => 
  return async (dispatch, getState) => 
    let userId = firebase.auth().currentUser.uid
    
    const confirmDate = moment(new Date()).format("ddd DD MMMM YYYY")

    const response = await fetch(
      `https://mymedicalbooking.firebaseio.com/bookings/$userId.json`,
      
        method: 'POST',
        headers: 
          'Content-Type': 'application/json'
        ,
        body: JSON.stringify(
          userId,
          therapistId,
          confirmDate,
          therapistFirstName,
          therapistLastName,
          sessionTime,
          sessionDate,
          slotTaken
        )
      
    );

    if (!response.ok) 
      throw new Error('Something went wrong!');
    

    const resData = await response.json();
   
    dispatch(
      type: ADD_BOOKING,
      bookingData: 
        userId: userId,
        therapistId: therapistId,
        therapistFirstName: therapistFirstName,
        therapistLastName: therapistLastName,
        sessionTime: sessionTime,
        sessionDate: sessionDate
      
    );
  ;
;

预订减少器:

const initialState = 
  bookings: [],
  userBookings: []
;

export default (state = initialState, action) => 
  switch (action.type) 
    case ADD_BOOKING:
      const newBooking = new Booking(
        action.bookingData.id,
        action.bookingData.therapistId,
        action.bookingData.therapistFirstName,
        action.bookingData.therapistLastName,
        action.bookingData.bookingdate
      );
      return 
        ...state,
        bookings: state.bookings.concat(newBooking)
      ;
    case FETCH_BOOKING:
      const userBookings = action.userBookings;
      return 
        ...state,
        userBookings: userBookings
      ;
  

  return state;
;

另外,我使用 expo、SDK 38、Firebase 作为数据库。

我真的需要解决这个问题,如果您有任何想法,请随时发表评论或回答所有问题。

更新:

我注释掉了所有深层链接功能并测试了结果,一切都很好。所以我认为问题出在eventListener 或者我如何实现我的深度链接代码,但我仍然不知道在 expo 中运行良好并且在独立时有错误的代码有什么问题。

更新 2

我尝试按照建议添加依赖数组,但我仍然遇到同样的问题..

【问题讨论】:

尝试将空依赖数组添加到您的useEffect,您可能会设置许多事件监听器,因为在每次状态/道具更改效果运行时(没有依赖数组的默认行为) 请查看here,您必须阅读note部分 @HagaiHarari 感谢您的建议,我试过了,但没有运气。同样的问题仍然存在。 【参考方案1】:

expo-linking 中存在一个问题,在独立分离的 android 应用上:事件 url 触发多次 ISSUE

我刚刚将我的处理函数封装在 lodash 的 debounce 中,等待 1000 毫秒

像这样安装lodash

yarn add lodash
import _ from 'lodash';

const handleOpenUrl = _.debounce((event) => 
    // here is other logic
  ,1000);

这是你的代码

只需在useEffect 中添加一个空的依赖数组,然后像这样使用useCallback

useEffect(() => 
    Linking.addEventListener('url', handleOpenUrl)
    return () => 
      Linking.removeEventListener('url', handleOpenUrl);
    

  ,[]);  //like this []
const handleOpenUrl = _.debounce((url) => 
    const route = url.replace(/.*?:\/\/\w*:\w*\/\W/g, '') // exp://.... --> ''
    const id = route.split('=')[1]

    if (id == 1) 
      handleDispatch();
      toggleModal();
     else if (id == 0) 
      console.log('purchase failed...');
      toggleModal();
    
  ,1000); //like this []
const handleDispatch = useCallback(() => 
    dispatch(
      BookingActions.addBooking(
        therapistId,
        therapistFirstName,
        therapistLastName,
        selected.title,
        moment(selectedDate).format("YYYY-MMM-DD"),
        selected.slots,
      )
    );

    dispatch(
      doctorActions.updateTherapists(therapistId, selected.slots, selectedDate, selected.title, selectedPlanIndex, selectedTimeIndex)
    );
    setBookingConfirm(true)
  ,[selected]) 

【讨论】:

谢谢你的回答兄弟,但如果我添加这个依赖数组,我最终会遇到另一个问题,即在从付款selected 状态数据消失后返回应用程序并且我的调度函数返回未定义。那我该如何处理呢? @EshgheCode 你可以在handleDispatch 的依赖数组中添加selected 状态。我已经更新了我的答案 我管理我的状态,我不再有任何问题,正如你所建议的,我做了所有的依赖数组,它正在工作,但在我再次测试 apk 文件之后,同样的事情发生了向 Firebase 预订了 2 次。 是的,它正在工作,我正在工作,抱歉迟到了。 兄弟,我的意思是它不是单独在调试模式下工作的,我在物理设备或模拟器上安装 apk 文件后仍然存在同样的问题。

以上是关于在我对独立应用程序 expo-deeplink 进行测试后,调度功能似乎运行了不止一次的主要内容,如果未能解决你的问题,请参考以下文章

3层架构业务逻辑层无逻辑

硬盘独立安装ubuntu,系统启动时默认进Win7,如何将ubuntu启动选项加到Win7启动选项?

线程归纳

独立显卡无法进入桌面怎么解决?

为什么想进大厂,一定要掌握Java异步编程技术

在 IIS 服务器上使用独立存储