Прослушиватель событий React-Native не отменяется при переходе на другой экран

Я разработчик React, и я впервые имею дело с React-native. У меня возникла досадная проблема, с которой я застрял на 2 дня.

У меня есть этот компонент:

imports

const OrderDetails = ({route}) => {
  const {OrderNumber} = route.params;
  const [items, setItems] = useState(null);
  const navigation = useNavigation();

   useEffect(() => {
    const fetchItemDetails = async () => {
      try {
        const response = await axios.get(
          `http://192.168.X.XX:5000/orders/${OrderNumber}`,
        );
        setItems(response.data);
        const handleScannerStatus = data => {
          onBarcodeScan(data.data, response.data.items);
        };

        RegisterScanner(handleScannerStatus);
      } catch (error) {
        console.info('error fetching order');
      }
    };
    fetchItemDetails();

    return () => {
      console.info('component unmounted');
      UnregisterScanner();
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [OrderNumber]);
  const onBarcodeScan = async (barcode, items) => {
    console.info("Scanning barcode from OrderDetails");
    const matchedProduct = items.find(item => barcode === item.tag);
    if (matchedProduct.Type === 'kit') {
      navigation.navigate('KitDetails', {
        OrderNumber,
        kit: matchedProduct,
      });
    } 
  };

  return (my jsx)
};

const styles = {...mystyles}
export default OrderDetails;

этот компонент в основном извлекает заказ и регистрирует событие, которое прослушивает отправку моего собственного модуля, и всякий раз, когда он находит элемент в заказе, который является комплектом, мы переходим к компоненту kitDetails, который выглядит следующим образом:

improts


const KitDetailsScreen = ({route}) => {
  const {OrderNumber, kit} = route.params;

  useEffect(() => {
    let handleScannerStatus = data => {
      console.info('Logging Barcode From KitDetails');
    };

    RegisterScanner(handleScannerStatus);

    return () => {
      console.info('unregister here');
      UnregisterScanner();
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  const tableHead = ['SKU', 'Fulfilled'];
  const tableData = kit.items.map(orderItem => [
    orderItem.sku,
    `${orderItem.Fulfilled}`,
  ]);

  return (jsx);
};

const styles = {...}
export default KitDetailsScreen;

Также я не думаю, что это будет иметь значение, но вот еще и прослушиватель событий:

import {NativeEventEmitter, NativeModules} from 'react-native';

const {BarcodeScannerModule} = NativeModules;
const eventEmitter = new NativeEventEmitter(BarcodeScannerModule);

export const RegisterScanner = handleScannerStatus => {
  eventEmitter.addListener('onBarcodeScanned', handleScannerStatus);

  BarcodeScannerModule.registerScannerStatusListener();
};

export const UnregisterScanner = () =>
  BarcodeScannerModule.unregisterScannerStatusListener();

Оба экрана выглядят очень похоже, но это не главное. Проблема здесь в том, что всякий раз, когда я перехожу к kitDetails, я все еще вижу console.infos из OrderDetails, я хочу, чтобы всякий раз, когда я перехожу к kitDetails, событие было отменено, и чтобы оно было доступно только в kitDetails, но навигация работает в странно, что он этого не делает.

Когда я начинаю сканирование внутри моего компонента kitDetails, вот результат:

 LOG  Logging Barcode From OrderDetails
 LOG  Logging Barcode From KitDetails
 LOG  Logging Barcode From OrderDetails
 LOG  Logging Barcode From KitDetails
 LOG  Logging Barcode From OrderDetails
 LOG  Logging Barcode From KitDetails

вместо этого он должен отображать только журнал KitDetails. Возможно, из-за того, что я новичок в React-native и что-то упускаю или не совсем понимаю, как работает поток, было бы неплохо дать мне несколько советов. При необходимости я также могу предоставить свой собственный код модуля.

То, что я пробовал и не сработало:

  1. переключение представлений внутри одного и того же компонента, но в моем случае это не работает.
  2. Отмена регистрации прямо перед переключением навигации.
  3. Зная тот факт, что размонтирование является асинхронным, я попытался добавить setTimeout к регистрации внутри kitDetails, но все равно смог увидеть журнал консоли обоих компонентов. Спасибо за внимание.
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
0
145
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Похоже, вы столкнулись с проблемой, из-за которой прослушиватель событий из компонента OrderDetails все еще активен даже после перехода к компоненту KitDetails. Это происходит потому, что функция очистки компонента OrderDetails, которая отменяет регистрацию прослушивателя событий, не запускается при переходе на другой экран.

Чтобы решить эту проблему, вы можете выполнить следующие шаги:

Переместите регистрацию и отмену регистрации прослушивателя событий сканера за пределы компонента и управляйте им на более высоком уровне, например, в родительском компоненте или контексте.

Используйте событие навигации для запуска функции очистки при выходе из компонента OrderDetails. Вот как вы можете изменить свой код для достижения этой цели:

Переместить регистрацию и отмену регистрации событий: Вместо регистрации и отмены регистрации прослушивателя событий внутри каждого компонента сделайте это на более высоком уровне, например, в родительском компоненте или контексте.

Запустить функцию очистки при навигации: Используйте событие навигации, например useFocusEffect из React Navigation, для запуска функции очистки при выходе из компонента OrderDetails.

Вот пример того, как вы можете выполнить рефакторинг своего кода (внесите изменения в соответствии с именем вашего компонента ):

спасибо за Ваш ответ! В некоторой степени это сработало: мне удалось успешно отменить регистрацию получателя в OrderDetails, но после того, как я зарегистрировал его обратно в KitDetails, я все еще могу видеть журналы. Это очень странное поведение, как будто это один компонент из двух разных файлов, я даже пытался это использовать: if (isFocused) { onBarcodeScan(data.data, response.data.items) } внутри OrderDetails, и когда я перейти в kitDetails Я все еще вижу лог, даже через эту проверку он все еще справляется, он вроде не расфокусируется, как навигация их так объединяет, я не понимаю?

Chrissisbeast 26.04.2024 15:10
Ответ принят как подходящий

В итоге я добавил два отдельных события для каждого компонента, и это решило проблему!

Другие вопросы по теме

React 18 новый способ обновления состояния или нет?
Проблема с компонентом рендеринга, созданная с использованием vite-plugin-svgr в шуточном тесте с использованием метода рендеринга библиотеки тестирования/реагирования
Асинхронные проблемы с useState в React Hooks
Ошибка: только простые объекты и несколько встроенных функций могут быть переданы клиентским компонентам из серверных компонентов. Классы или нулевые прототипы не поддерживаются
Как дождаться завершения вызовов API, прежде чем создавать еще один, когда они находятся в своих собственных функциях?
Eslint – невозможно разрешить путь к модулю @web3modal/ethers/react, import/no-unresolved
Сбой подключения NodeJS к CosmosDB при создании клиента из строки подключения
Как применить разные стили для многоразовой кнопки реагирования с помощью Mui
Как запустить повторный рендеринг компонента реагирования после изменения параметра запроса (без реагирования-маршрутизатора)
Медленный запуск vite с булочкой