How to generate and download QR code in a React Native application
Published: 2022-07-16 19:23:44


**Background:**
QR Codes are scannable codes that store data. QR stands for **Quick Response**. They serve a great purpose in accessing information forexample items in a supermarket have a QR codes that contain product information say item name, date of expiry, details about product manufacturer e.g their phone number etc.

**Onto coding🥳**
With that background information, let's dig deep into how we can generate and download QR codes in a react native application. First, we need to install 2 dependency packages i.e **react-native-svg** and **react-native-qrcode-svg**. 
You can use npm or yarn to install the two dependencies under the root directory of your project using the commands below;
```javascript
npm i -S react-native-svg react-native-qrcode-svg
```
OR
```javascript
yarn add react-native-svg react-native-qrcode-svg
```

**Reusable component QRCODE example**
In the following example, I create a reusable hook component called QRCODE;

```javascript
import React from 'react';
import QRCode from 'react-native-qrcode-svg';

const QRCODE = ({value, getRef}) => {
    return(
        <QRCode
        value={value}
        size={250}
        color="black"
        backgroundColor="white"
        getRef={getRef}
        />
        )
    }
 
export default QRCODE
```
In the above hook, I import QRCode from react-native-qrcode-svg package. Then the custom reusable hook **QRCODE** takes in 2 props i.e value & getRef. **value** is string value of the QR code (When you scan the QR code, value is the information that gets displayed) while **getRef** is the svg ref of the QR code that can be used further(as we are going to see when downloading/saving this QR code to gallery).

In the return statement, QRCode hook from the dependency, has props i.e value, size, color of the QR code and getRef prop.

**Using reusable hook QRCODE**
In the following code example, I demonstrate how you can use the reusable hook created above to generate QR Code.

```javascript
import React, { useState } from 'react';
import { View, StyleSheet } from 'react-native';
import QRCODE from '../components/QRcode';

const App = () => {

  const initialItemState ={
    name: 'Sugar',
    expiryDate: '2023-12-31',
    manufacturer: 'Kakira Sugar Estate'
  }

  const [item, setItem] = useState(initialItemState);
  const [productQRref, setProductQRref] = useState();

  return (
  <View>
   <QRCODE 
      value={JSON.stringify({
       name: item.name,
       expiry: item.expiryDate,
       manufacturer: item.manufacturer
      })}
      getRef={(c) => setProductQRref(c)}/>
  </View>
  )
}
export default App;

const styles = StyleSheet.create({
   container:{
    flex: 1,
    alignItems: 'center'
  }
});
```
In the above code, I import reusable hook we created before, and then pass properties, values and getRef with their corresponding values. Value is an item with keys; name, expiryDate and manufacturer. Because value prop to QRCODE is a string, I use JSON.stringify to convert item object to a string.

**Downloading the generated QR code to Gallery**
Well, I talked of **useRef** as the property passed to QRcode to get svg ref of the QR code.
In that case, I use setProductQRref hook to store the state of the svg ref of the QR code as seen in the above code.

In order to save QR code to gallery, we need two dependencies i.e **@react-native-community/cameraroll** and **react-native-fs**.  @react-native-community/cameraroll is a react-native native module that provides access to the local camera roll or photo library while react-native-fs is the library that can make you use the filesystem easily in react native.

**Code example for saving QR Code to photo gallery**
```javascript
import { 
Platform,
PermissionsAndroid,
ToastAndroid }
 from 'react-native';
import RNFS from "react-native-fs";
import CameraRoll from "@react-native-community/cameraroll";

 const saveQrToDisk = async(item) => {

if (Platform.OS === "android" &&
 !(await hasAndroidPermission())) {
     return;
}

if(productQRref){

productQRref.toDataURL((data) => {
   
let filePath =  RNFS.CachesDirectoryPath+`/${item.name}.png`;
RNFS.writeFile(filePath, data, 'base64')
  .then((success) => {
    return CameraRoll.save(filePath, 'photo')
  })
 .then(() => {
ToastAndroid.show('QRCode saved to gallery', ToastAndroid.LONG);
          });
   });
   }
 }

const hasAndroidPermission = async() => {
const permission=
PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE;

  const hasPermission = 
await PermissionsAndroid.check(permission);
  if (hasPermission) {
    return true;
  }

  const status = await PermissionsAndroid.request(permission);
  return status === 'granted';
}
```
saveQrToDisk is my function name, used to save QR code to gallery, it uses productQRref, the svg ref of the QR code we created in the previous code example. toDataURL function returns returns a data URL containing a representation of the QR code image. The imported RNFS hook writes the filePath of the QR code on the disk. When the path is finally written, I then use CameraRoll.save hook to save the QR code to the created file path on the disk.

hasAndroidPermission hook is used to request permissions to write to phone storage if not enabled.

**Full Code example for generating and downloading QR code**
```javascript
import React, { useState } from 'react';
import { View, StyleSheet,Platform, PermissionsAndroid,
         ToastAndroid, Text, TouchableOpacity  } 
from 'react-native';
import QRCODE from '../components/QRcode';
import RNFS from "react-native-fs";
import CameraRoll from "@react-native-community/cameraroll";

const App = () => {

  const initialItemState ={
    name: 'Sugar',
    expiryDate: '2023-12-31',
    manufacturer: 'Kakira Sugar Estate'
  }

  const [item, setItem] = useState(initialItemState);
  const [productQRref, setProductQRref] = useState();

const saveQrToDisk = async() => {

if (Platform.OS === "android" &&
 !(await hasAndroidPermission())) {
     return;
}

if(productQRref){

productQRref.toDataURL((data) => {
   
let filePath =  RNFS.CachesDirectoryPath+`/${item.name}.png`;
RNFS.writeFile(filePath, data, 'base64')
  .then((success) => {
    return CameraRoll.save(filePath, 'photo')
  })
 .then(() => {
ToastAndroid.show('QRCode saved to gallery', ToastAndroid.LONG);
          });
   });
   }
 }

 const hasAndroidPermission = async() => {
const permission=
PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE;

  const hasPermission = 
await PermissionsAndroid.check(permission);
  if (hasPermission) {
    return true;
  }

  const status = await PermissionsAndroid.request(permission);
  return status === 'granted';
}

  return (
  <View style={styles.container}>
    <Text style={styles.qrText}>QR Code</Text>
   <QRCODE 
      value={JSON.stringify({
       name: item.name,
       expiry: item.expiryDate,
       manufacturer: item.manufacturer
      })}
      getRef={(c) => setProductQRref(c)}/>
  <TouchableOpacity 
      style={styles.button}
      onPress={() => { saveQrToDisk() }}>
     <Text style={styles.save}>Save to Gallery</Text>
   </TouchableOpacity>
  </View>
  )
}
export default App;

const styles = StyleSheet.create({

  container:{
    flex: 1,
    backgroundColor: '#fff',
    justifyContent: 'center',
    alignItems: 'center'
  },

  button: {
    borderRadius:30,
    padding:15,
    position: 'absolute',
    bottom: 0,
    width: '90%',
    justifyContent: 'center',
    alignItems: 'center',
    fontWeight: 'bold',
    marginBottom: 30,
    color: '#fff',
    backgroundColor:"#273746"
  },

  qrText: {
    top: -20,
    color: '#000',
    fontSize:18,
    fontWeight: 'bold'
  },

  save: {
    color: '#fff',
    fontSize:16,
    textTransform: 'capitalize'
 }
});
```
**Output on your emulator or phone device screen**
![Output on your emulator or phone device screen](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sfcunvqcnifmpzm5b88c.jpg)

That's how you can generate QR Code and save it to gallery in a react native application. Thank you for reading through this article. Today was a long class, oops!!!😌 But thank you!!🤗