Search code examples
react-nativeroutesreact-propsreact-navigation-v5react-native-camera

navigate to another page with data in react native


I'm using react-native and react-navigation v5. I wanted to navigate to another page after the function executes.
I am using react native camera. After I take the picture I want the app to navigate to another page with the data of the image. is there a way to do it.

import React, { PureComponent } from 'react';
import { StyleSheet, Text, TouchableOpacity, View } from 'react-native';
import { RNCamera } from 'react-native-camera';

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

class CameraComponent extends PureComponent {
  render() {
    return (
      <View style={styles.container}>
        <RNCamera
          style={styles.preview}
          type={RNCamera.Constants.Type.back}
          flashMode={RNCamera.Constants.FlashMode.on}
          androidCameraPermissionOptions={{
            title: 'Permission to use camera',
            message: 'We need your permission to use your camera',
            buttonPositive: 'Ok',
            buttonNegative: 'Cancel',
          }}
          androidRecordAudioPermissionOptions={{
            title: 'Permission to use audio recording',
            message: 'We need your permission to use your audio',
            buttonPositive: 'Ok',
            buttonNegative: 'Cancel',
          }}
        >
          {({ camera, status, recordAudioPermissionStatus }) => {
            if (status !== 'READY') return <PendingView />;
            return (
              <View style={{ flex: 0, flexDirection: 'row', justifyContent: 'center' }}>
                <TouchableOpacity onPress={() => this.takePicture(camera)} style={styles.capture}>
                  <Text style={{ fontSize: 14 }}> SNAP </Text>
                </TouchableOpacity>
              </View>
            );
          }}
        </RNCamera>
      </View>
    );
  }

  takePicture = async function(camera) {
    const options = { quality: 0.5, base64: true };
    const data = await camera.takePictureAsync(options);
    //  eslint-disable-next-line
    console.log(data.uri);
  };
}

export default CameraComponent

Solution

  • If CameraComponent is one of the screens of your navigation, then you should make it as a normal component because it will receive a navigation param that you will use it in navigation like so:

    class CameraComponent extends Component({navigation}) {
    ...
      takePicture = async function(camera) {
        const options = { quality: 0.5, base64: true };
        const data = await camera.takePictureAsync(options);
        //  eslint-disable-next-line
        console.log(data.uri);
        navigation.navigate('any-other-page', {
          imgData: data
        });
      };
    }
    

    More info can be found in Moving between screens docs of react-navigation
    And info about passing data and getting data can be found in Passing parameters to routes docs


    There are cases where CameraComponent will not be part of the screens of the navigation, rather, it will be a child/nested child of it.
    There are three different solutions to this:

    If the CameraComponent is a direct child of the navigation screen
    Then you simply pass the navigation prop to the child, like so:

    class ParentScreen extends Component({navigation}) {
    ...
      <CameraComponent navigation={navigation} />
    }
    

    and then use the navigation prop as we did above.

    If the CameraComponent is a deeply nested child of the navigation screen
    This will be quite difficult to explain here, but in short, you will use react context to do this if you want to keep your react components as class components

    If the CameraComponent is a deeply nested child of the navigation screen
    You can change your react components to be functional components and then use the more easy way: useNavigation Hook like so:

    function CameraComponent () {
      const navigation = useNavigation();
    ...
      takePicture = async function(camera) {
        const options = { quality: 0.5, base64: true };
        const data = await camera.takePictureAsync(options);
        //  eslint-disable-next-line
        console.log(data.uri);
        navigation.navigate('any-other-page', {
          imgData: data
        });
      };
    }```