You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native NFC Manager iOS端快速取消后无法正常工作问题排查

React Native NFC Manager 快速重复触发无响应问题

我使用React Native NFC Manager开发基础NFC读取应用时遇到以下问题:点击TouchableOpacity启动扫描弹窗后,通过取消按钮关闭弹窗,若过快再次点击按钮,界面无任何反应,且无报错信息,推测该问题与NFC进程耗时有关。

原代码

import React, {useState} from 'react';
import {View, Text, TouchableOpacity, StyleSheet} from 'react-native';
import NfcManager, {NfcTech} from 'react-native-nfc-manager';

// Pre-step, call this before any NFC operations
NfcManager.start();

function App() {
  const [loaded, setLoaded] = useState(true);
  async function readNdef() {
    try {
      setLoaded(false);
      // register for the NFC tag with NDEF in it
      await NfcManager.requestTechnology(NfcTech.Ndef);
      // the resolved tag object will contain `ndefMessage` property
      const tag = await NfcManager.getTag();
      console.warn('Tag found', tag);
    } catch (ex) {
      console.warn('Oops!', ex);
    } finally {
      // stop the nfc scanning
      try {
        await NfcManager.cancelTechnologyRequest();
      } catch (ex) {
        console.warn('Error while canceling technology request', ex);
      } finally {
        setLoaded(true);
      }
    }
  }

  return (
    <View style={styles.wrapper}>
      {loaded && (
        <TouchableOpacity onPress={readNdef}>
          <Text style={{color: 'white'}}>Scan a Tag</Text>
        </TouchableOpacity>
      )}
    </View>
  );
}

const styles = StyleSheet.create({
  wrapper: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
});

export default App; 

问题原因

  • cancelTechnologyRequest是异步操作,快速重复触发时,前一次的取消操作尚未完成,后一次的requestTechnology已发起,导致NFC管理器处于状态不一致的情况。
  • 原代码中setLoaded(true)是在finally块同步执行,未等待cancelTechnologyRequest完成,导致UI提前恢复可点击,但实际NFC进程还未清理完毕。

解决方案

通过新增状态跟踪NFC操作的实际状态,确保前一次所有NFC操作(包括取消)完成后,才允许触发下一次扫描:

import React, {useState} from 'react';
import {View, Text, TouchableOpacity, StyleSheet} from 'react-native';
import NfcManager, {NfcTech} from 'react-native-nfc-manager';

NfcManager.start();

function App() {
  const [isScanning, setIsScanning] = useState(false);

  async function readNdef() {
    // 防止重复触发
    if (isScanning) return;
    
    setIsScanning(true);
    try {
      await NfcManager.requestTechnology(NfcTech.Ndef);
      const tag = await NfcManager.getTag();
      console.warn('Tag found', tag);
    } catch (ex) {
      console.warn('Oops!', ex);
    } finally {
      // 等待取消操作完成后再更新状态
      try {
        await NfcManager.cancelTechnologyRequest();
      } catch (ex) {
        console.warn('Error while canceling technology request', ex);
      } finally {
        setIsScanning(false);
      }
    }
  }

  return (
    <View style={styles.wrapper}>
      {!isScanning && (
        <TouchableOpacity onPress={readNdef}>
          <Text style={{color: 'white'}}>Scan a Tag</Text>
        </TouchableOpacity>
      )}
    </View>
  );
}

const styles = StyleSheet.create({
  wrapper: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
});

export default App;

优化说明

  • 使用isScanning状态替代原loaded状态,统一管理扫描操作的状态。
  • 在readNdef函数开头增加判断,若当前正在扫描则直接返回,避免重复触发。
  • 确保cancelTechnologyRequest异步操作完成后,才将isScanning设为false,保证NFC进程完全清理后才允许下一次操作。

内容的提问来源于stack exchange,提问作者user19363667

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 21:05:29