即使使用清理功能,React 本机深层链接不需要的组件也会呈现

问题描述

我的深层链接句柄 URL 存在问题,这是我的组件在 URL 到达我的应用程序后多次呈现。换句话说,假设浏览器在客户端选择所需的会话时间(由状态处理)后打开购买操作,并且在客户端决定购买或取消后,应用程序打开以显示结果,但它会多次执行.

这是组件的一部分:

const bookingHandler = () => {
    if(selected == null) {
      Alert.alert('Invalid Selection','Please select one of the sessions!')
      return;
    }
    Linking.openURL('http://www.medicalbookingapp.cloudsite.ir/sendPay.PHP');
  }

  selectedTimeIndex = therapists.meetingPlans[selectedplanIndex].times.findindex((el) => el.time == selected.title);
 
  useEffect(() => {

    Linking.addEventListener('url',(e) => handleOpenUrl(e.url))

    return () => {
      Linking.removeEventListener('url',(e) => handleOpenUrl(e.url));
      console.log('event removed')
    } 
    
  });

  const handleOpenUrl = (url) => { 
    const route = url.replace(/.*?:\/\/\w*:\w*\/\W/g,'') // exp://myapplication.... --> ''
    const id = route.split('=')[1]
    
    if(id == 1) {
      dispatch(
        BookingActions.addBooking(
          therapistId,therapistFirstName,therapistLastName,selected.title,moment(selectedDate).format("YYYY-MMM-DD"),selected.slots,)
      );
      

      dispatch(
        doctorActions.updateTherapists(therapistId,selectedDate,selectedplanIndex,selectedTimeIndex)
      );
      setBookingConfirm(true)
      toggleModal();

    } else if(id == 0) {
      console.log('purchase Failed...');
      toggleModal();
    }
  }

我在 useEffect 钩子内处理我的监听器,它还有清理功能。但在控制台中我收到此错误

Can't perform a React state update on an unmounted component. This is a no-op,but it indicates a memory leak in your application. To fix,cancel all subscriptions and asynchronous tasks in %s.%s,a useEffect cleanup function.

我还注意到了一些其他的东西,为了抓住问题,你可以看到组件屏幕,会话选择部分是用 state 处理的。呈现 useEffect 钩子的数量与选择会话状态的更改数量有某种关系。 (我的意思是如果我在选择会话中弹跳,它会呈现更多)

enter image description here

如果您需要更多信息,请在评论中告诉我。 任何帮助将不胜感激。

解决方法

一个可能的问题是您可能会创建两个处理程序,一个在 addListener 中,另一个在 removeListener 中。

你能不能试试:

const handler = (e) => handleOpenUrl(e.url);
Linking.addEventListener('url',handler);

return () => {
   Linking.removeEventListener('url',handler);
   console.log('event removed')
}