我是一名 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.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;
这个组件基本上获取订单并注册一个事件,该事件侦听我的本机模块发送的发射,每当它在订单中找到一个套件项目时,我们就会导航到 kitDetails 组件,如下所示:
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;
另外,我认为这并不重要,但这也是事件监听器:
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 时,我仍然会看到来自 OrderDetails 的 console.logs,我希望每当我导航到 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 日志。 也许是因为我是反应原生的新手,我错过了一些东西或者不完全理解流程是如何工作的,如果你能给我一些指示,那就太好了。 如果需要,我也可以提供我的本机模块代码。
我尝试过但不起作用的事情是:
您似乎面临这样一个问题:即使导航到 KitDetails 组件后,OrderDetails 组件中的事件侦听器仍然处于活动状态。发生这种情况是因为导航到另一个屏幕时不会触发 OrderDetails 组件的清理函数(该函数会取消注册事件侦听器)。
要解决此问题,您可以按照以下步骤操作:
将扫描仪事件侦听器的注册和取消注册移到组件外部,并在更高级别进行管理,例如在父组件或上下文中。
当离开 OrderDetails 组件时,使用导航事件触发清理函数。 您可以通过以下方式修改代码来实现此目的:
移动事件注册和注销: 不要在每个组件内注册和取消注册事件侦听器,而是在更高级别上进行,例如在父组件或上下文中。
导航触发清理功能: 利用导航事件(例如 React Navigation 中的 useFocusEffect)在离开 OrderDetails 组件时触发清理功能。