首页 > 解决方案 > react-native-camera 条形码扫描仪冻结,因为它扫描速度太快

问题描述

我正在尝试使用react-native-camera. 首先,它扫描二维码并提取一个字符串,然后导航到下一个屏幕react-navigation。在第二个屏幕中,它进行 API 调用。

现在,如果我返回扫描仪屏幕,将立即扫描二维码。那就是我遇到错误并且扫描仪冻结的地方。我通常会收到此错误:

Can't call setState (or forceUpdate) on an unmounted component

我认为这是因为我的componentWillUnmount清理工作不正常或不够快,但我已经取消了 axios 请求。

       requestCode = (code) => {
        if (cancel != undefined) {
          cancel();
        }
        axios.get(API_URI + code, {
          cancelToken: new CancelToken(function executor(c) {
            cancel = c;
          })
        }).then(response => {
          console.log(response)
          //checks if code was already called
          this.checkUsed(response.data)
        })
          .catch(error => {
            this.setState({ isValid: false })
          });
        }

    componentWillUnmount() {
        cancel();
      }

也许我可以稍后安装相机扫描仪,这样它就不会扫描得这么快,或者它甚至可能是 React Navigation 的错误?

标签: react-nativereact-native-iosreact-native-camerareact-lifecycle

解决方案


您可以使用标志来控制。

class QR extends Component {
  constructor(props) {
    super(props)

    this.state = {
      scanable: true
    }

    this.cameraAttrs = {
      ref: ref => {
        this.camera = ref
      },
      style: styles.preview,
      type: RNCamera.Constants.Type.back,
      barCodeTypes: [RNCamera.Constants.BarCodeType.qr],
      onBarCodeRead: ({ data }) => {
        this.callback(data)
      }
    }
  }

  componentWillMount() {
    this._mounted = true
  }

  componentWillUnmount() {
    this._mounted = false
  }

  callback(text) {
    if (!this.state.scanable) {
      return
    }

    console.log(text)
    this.setState({ scanable: false })
    setTimeout(() => {
      if (this._mounted) {
        this.setState({ scanable: true })
      }
    }, 1000) // 1s cooldown
  }

  render() {
    return (
      <View style={styles.container}>
        <RNCamera
          {...this.cameraAttrs}
        >
        </RNCamera>
      </View>
    )
  }
}

推荐阅读