javascript - 如何一次扫描一个条码? [ react native 相机]

标签 javascript android reactjs react-native react-native-camera

实际上,我是 React 新手,我正在尝试制作一个简单的条形码扫描仪,它在警报中显示扫描的条形码,在警报中按“确定”后,用户应该能够扫描另一个条形码。

问题在于条形码会被连续扫描,当警报出现时,它会隐藏并每秒显示警报。

我试图做这样的事情,只显示一次警报,如果按下“确定”,则能够再次显示警报,但只有在按下“确定”但没有效果的情况下。

  onBarCodeRead = (e) => {
    if(!this.alertPresent){
      this.alertPresent = true;
          Alert.alert(
            "Barcode type is " + e.type,
            "Barcode value is " + e.data,
            [
                 {text: 'OK', onPress: () => this.alertPresent = false;},
            ],
              {cancelable: false},
          );
      }
  }

这里是Barcode.JS的完整代码

import React, { Component } from 'react';
import { Button, Text, View,Alert } from 'react-native';
import { RNCamera } from 'react-native-camera';
import BarcodeMask from 'react-native-barcode-mask';
class ProductScanRNCamera extends Component {

  constructor(props) {
    super(props);
    this.camera = null;
    this.barcodeCodes = [];
    this.alertPresent = false;
    this.state = {
      camera: {
        flashMode: RNCamera.Constants.FlashMode.auto,
      }
    };
  }

  onBarCodeRead = (e) => {
    if(!this.alertPresent){
      this.alertPresent = true;
          Alert.alert(
            "Barcode type is " + e.type,
            "Barcode value is " + e.data,
            [
                 {text: 'OK', onPress: () => this.alertPresent = false;},
            ],
              {cancelable: false},
          );
      }
  }


  pendingView() {
    return (
      <View
      style={{
        flex: 1,
        backgroundColor: 'lightgreen',
        justifyContent: 'center',
        alignItems: 'center',
      }}
      >
      <Text>Waiting</Text>
      </View>
    );
  }

  render() {


    return (
      <View style={styles.container}>
      <RNCamera
      ref={ref => {
        this.camera = ref;
      }}
      defaultTouchToFocus
      flashMode={this.state.camera.flashMode}
      mirrorImage={false}
      onBarCodeRead={this.onBarCodeRead.bind(this)}
      onFocusChanged={() => {}}
      onZoomChanged={() => {}}
      style={styles.preview}
      >
      <BarcodeMask/>
      </RNCamera>
      </View>
    );
  }
}

最佳答案

这里的技巧是使用内部状态修改 barcodeTypes 属性。

const defaultBarcodeTypes = [// should be all Types from RNCamera.Constants.BarCodeType];

class ProductScanRNCamera extends Component {
   state = {
      // your other states
      barcodeType: '',
      barcodeValue: '',
      isBarcodeRead: false // default to false
   }

   onBarcodeRead(event) {
      this.setState({isBarcodeRead: true, barcodeType: event.type, barcodeValue: event.data});
   }

   // run CDU life-cycle hook and check isBarcodeRead state
   // Alert is a side-effect and should be handled as such.
   componentDidUpdate() {
      const {isBarcodeRead, barcodeType, barcodeValue} = this.state;
      if (isBarcodeRead) {
         Alert.alert(barcodeType, barcodeValue, [
           { 
               text: 'OK', 
               onPress: () => {
                   // Reset everything 
                   this.setState({isBarcodeRead: false, barcodeType: '', barcodeValue: ''})
               }
           }
         ]);
      }

   }

   render() {
      const {isBarcodeRead} = this.state;
      return (
         <RNCamera {...your other props} barcodeTypes={isBarcodeRead ? [] : defaultBarcodeTypes}>
            <BarcodeMask />
         </RNCamera>
      )

   }
}

钩子(Hook)版本更干净

const ProductScanRNCamera = () => {
   const [isBarcodeRead, setIsBarcodeRead] = useState(false);
   const [barcodeType, setBarcodeType] = useState('');
   const [barcodeValue, setBarcodeValue] = useState('');

   useEffect(() => {
      if (isBarcodeRead) {
          Alert.alert(
             barcodeType, 
             barcodeValue, 
             [
                {
                    text: 'OK',
                    onPress: () => {
                        // reset everything
                        setIsBarcodeRead(false);
                        setBarcodeType('');
                        setBarcodeValue('');
                    }
                }
             ]
          );
      }

   }, [isBarcodeRead, barcodeType, barcodeValue]);

   const onBarcodeRead = event => {
      if (!isBarcodeRead) {
         setIsBarcodeRead(true);
         setBarcodeType(event.type);
         setBarcodeValue(event.data);
      }
   }

   return (
      <RNCamera {...your props} 
                onBarCodeRead={onBarcodeRead} 
                barcodeTypes={isBarcodeRead ? [] : defaultBarcodeTypes}>
         <BarcodeMask />
      </RNCamera>
   )
}

关于javascript - 如何一次扫描一个条码? [ react native 相机],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58284343/

相关文章:

javascript - AngularJS 多类 ="{{class1}} {{class2}}"按单词自动排序?

javascript - 删除 DOM 中的元素

java - 在不滚动到顶部的情况下更新 recyclerView 适配器

android - 如何在 Android 中以编程方式打开/更改 Google Ads 选择退出设置?

android - 如何从url获取JSON数据?

css - div之间的过渡ReactJS

reactjs - 当我使用 Turbopack 运行 Next.js 13 时,我得到 "TypeError: Class extends value #"但 webpack 没有错误

javascript - 计算多种货币格式元素的总和

javascript - 搜索页面的客户端和服务器端(ajax)渲染之间的区别,涉及 SEO

javascript - Bootstrap 模式未正确呈现