skip to Main Content

I am a React developer and this is my first time dealing with react-native, I have this annoying problem I’ve been stuck for 2 days.

I have this component:

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.log('error fetching order');
      }
    };
    fetchItemDetails();

    return () => {
      console.log('component unmounted');
      UnregisterScanner();
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [OrderNumber]);
  const onBarcodeScan = async (barcode, items) => {
    console.log("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;

this component basically fetches the order and registers an event that listens for an emit my native module sends and whenever it finds an item in the order that is a kit, we get navigated to the kitDetails component, which looks like this:

improts


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

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

    RegisterScanner(handleScannerStatus);

    return () => {
      console.log('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;

Also I don’t think it will matter, but here is the Event Listener as well:

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();

The two Screens look very similar, but that is besides the point. The problem here is, whenever I navigate to the kitDetails, I still see the console.logs from the OrderDetails, I want whenever I navigate to kitDetails the event to Unregister and for it to only be available in the kitDetails, but navigation works in a weird way that it doesn’t do that.

When I start scanning inside my kitDetails component, this is the output:

 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

instead it should only show the KitDetails log.
Maybe due to the fact I am new to react-native and I am missing something or don’t exactly understand how the flow works, if you can give me some pointers that would be nice.
I can provide my native module code as well if needed.

The things I tried and didn’t work are:

  1. switching views inside the same component but that doesnt really work for my case.
  2. Unregistering right before the navigation switch.
  3. Knowing the fact that unmount is asynchronous, I tried adding a setTimeout to the registering inside kitDetails, but still was able to see the console log of both components.
    Thanks for your attention.

2

Answers


  1. Chosen as BEST ANSWER

    I ended up adding two separate events in each events and that solved the issue!


  2. It seems like you’re facing an issue where the event listener from the OrderDetails component is still active even after navigating to the KitDetails component. This occurs because the OrderDetails component’s cleanup function, which unregisters the event listener, isn’t triggered when navigating to another screen.

    To solve this issue, you can follow these steps:

    Move the registration and unregistration of the scanner event listener outside of the component and manage it at a higher level, such as in a parent component or a context.

    Use a navigation event to trigger the cleanup function when navigating away from the OrderDetails component.
    Here’s how you can modify your code to achieve this:

    Move Event Registration and Unregistration:
    Instead of registering and unregistering the event listener inside each component, do it at a higher level, such as in a parent component or a context.

    Trigger Cleanup Function on Navigation:
    Utilize a navigation event, such as useFocusEffect from React Navigation, to trigger the cleanup function when navigating away from the OrderDetails component.

    Here’s an example of how you can refactor your code (Make changes as per your component’s nameenter image description here):

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search