Search code examples
javascriptreact-nativereact-hooksreact-props

Which component should I use class or functional?


I'm trying to use react-native-camera and I want to send tokens from the first page to the camera page. how can I get a token on the camera page? I am not sure how to solve this problem, I tried to change the camera page to function based component but I get more errors :) so I'd be very happy if you guys help me out

the first page is function-based component

import React from 'react';
import {View, Text, TouchableOpacity, ActivityIndicator} from 'react-native';

const first = () => {
  const token = '12345678';

  return (
    <View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
      {isData?(
        <TouchableOpacity
        onPress={() => {
          navigation.navigate('cameraV2', {token:token});
        }}
        style={{
          height: 50,
          width: '80%',
          backgroundColor: '#f45f00',
          alignItems: 'center',
          justifyContent: 'center',
        }}>
        <Text style={{fontWeight: 'bold', fontSize: 18}}>
          Giriş için tıklayın
        </Text>
      </TouchableOpacity>
      ):(
        <ActivityIndicator size='large' color='#0f0' />
      )}
    </View>
  );
};

export default first;

camera page is class based component

import React, {Component} from 'react';
import {Button, Text, View} from 'react-native';
import {RNCamera} from 'react-native-camera';


class cameraV2 extends Component {
  navigation = this.props.navigation;
  constructor(props) {
    super(props);
    this.camera = null;
    this.barcodeCodes = [];

    this.state = {
      token:this.navigation.token,
      is_camera: 0,
      is_loading: 0,
      barcodes: [],
      camera: {
        type: RNCamera.Constants.Type.back,
        flashMode: RNCamera.Constants.FlashMode.auto,
      },
    };
  }

  barcodeRecognized = ({barcodes}) => {
    barcodes.forEach(barcode => {
        if(barcode.type!=='UNKNOWN_FORMAT'){
          console.log(barcode.data)
            this.setState({barcodes});
        }
    });
  };

  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)}
          onGoogleVisionBarcodesDetected={this.barcodeRecognized}
          onFocusChanged={() => {}}
          onZoomChanged={() => {}}
          permissionDialogTitle={'Permission to use camera'}
          permissionDialogMessage={
            'We need your permission to use your camera phone'
          }
          style={styles.preview}
          type={this.state.camera.type}
        />
        <View style={[styles.overlay, styles.topOverlay]}>
          <Text style={styles.scanScreenMessage}>Please scan the barcode.</Text>
          <Text style={styles.scanScreenMessage}>token: {this.state.token} </Text>
        </View>
        <View style={[styles.overlay, styles.bottomOverlay]}>
          <Button
            onPress={() =>
              this.navigation.navigate('second', {
                barcode: this.state.barcodes,
                token: token,
              })
            }
            style={styles.enterBarcodeManualButton}
            title="Enter Barcode"
          />
        </View>
      </View>
    );
  }
}

const styles = {
  container: {
    flex: 1,
  },
  preview: {
    flex: 1,
    justifyContent: 'flex-end',
    alignItems: 'center',
  },
  overlay: {
    position: 'absolute',
    padding: 16,
    right: 0,
    left: 0,
    alignItems: 'center',
  },
  topOverlay: {
    top: 0,
    flex: 1,
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
  },
  bottomOverlay: {
    bottom: 0,
    backgroundColor: 'rgba(0,0,0,0.4)',
    flexDirection: 'row',
    justifyContent: 'center',
    alignItems: 'center',
  },
  enterBarcodeManualButton: {
    padding: 15,
    backgroundColor: 'white',
    borderRadius: 40,
  },
  scanScreenMessage: {
    fontSize: 14,
    color: 'white',
    textAlign: 'center',
    alignItems: 'center',
    justifyContent: 'center',
  },
};

export default cameraV2;


Solution

  • You just need to initialise the state with token value from route params obtained from props instead of navigation

    this.state = {
          token: this.props.route.params.token,
          is_camera: 0,
          is_loading: 0,
          barcodes: [],
          camera: {
            type: RNCamera.Constants.Type.back,
            flashMode: RNCamera.Constants.FlashMode.auto,
          },
        };
      }
    

    P.S You do not need to convert the entire component to functional component just for using params