Actually i'm new to React and i'm trying to make a simple barcode scanner which show the scanned barcode in an alert and after pressing "OK" in the alert the user should be able to scan another barcode.
The issue is that the barcode is continuously scanned and when the alert is up it's hiding and showing every second the alert.
I was trying to do something like this to show the alert only once and if OK is pressed to be able to show again the alert but only in case the OK is pressed but that had no effect..
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},
);
}
}
Here is full code of 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>
);
}
}
The trick here is to modify barcodeTypes
props with an internal state.
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>
)
}
}
A hook version is cleaner
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>
)
}