How to Upload File/Image to Server with Form Data in React Native

Uploading File in React Native

In this post, I’ll show you how to Upload File/Image to Server with Form Data in React Native. This example will cover how to pick any file from the file system and upload it to the server. I have also shared the server-side PHP code with the React Native File upload example.

If you noticed the title we are going to use FormData to upload the File on the server because I personally do not like to add third-party dependencies in my projects as long as using those dependencies is the last option.

Why I use FormData for File Uploading in React Native?

If you search for the file uploading examples in React Native over the internet you will find many examples and most of them have used external third party dependencies to upload the file on the server, but I personally try to avoid the third-party dependencies and like to find the other solution and FormData is one of them. The reason for avoiding third-party dependencies and using FormData is

  1. Third-party dependencies can make your project bulky
  2. Managing the proper version of dependencies
  3. After the major update of the dependencies, you need to update the project as well
  4. It is very tough to update others code in case of small update required
  5. The special thing about FormData is that network methods, such as fetch, can accept a FormData object as a body. It is encoded and sent out with Content-Type: multipart/form-data.

These are the primary reasons for which I use FormData for File Uploading.

How to use FormData for File Uploading in React Native?

Uploading a file using FormDate is very simple. It is divided into 3 steps:

  1. Pick a file using any file picker. Here I am using react-native-document-picker for file picking
    const res = await DocumentPicker.pick({
        type: [DocumentPicker.types.allFiles],
    });
    this.setState({ singleFile: res });
  2. Create FormData by creating an object and appending the values you want to send to the server
    const data = new FormData();
    data.append('name', 'Image Upload');
    data.append('file_attachment', fileToUpload);
  3. Using fetch method calling a file upload web service which will send the created FormData as a multipart/form-data to upload the file
    let uploadImage = async () => {
        //Check if any file is selected or not
        if (singleFile != null) {
          //If file selected then create FormData
          const fileToUpload = singleFile;
          const data = new FormData();
          data.append('name', 'Image Upload');
          data.append('file_attachment', fileToUpload);
          let res = await fetch(
            'http://localhost//webservice/user/uploadImage',
            {
              method: 'post',
              body: data,
              headers: {
                'Content-Type': 'multipart/form-data; ',
              },
            }
          );
          let responseJson = await res.json();
          if (responseJson.status == 1) {
            alert('Upload Successful');
          }
        } else {
          //if no file selected the show alert
          alert('Please Select File first');
        }
    };

What We are Going to Create in Uploading File Example?

In this example, We are going to create one Screen with two buttons. One button to pick the file from the file system and another button to upload the file on the server.

If you face any challenge with the file picker then you can see Example of File Picker in React Native it will help you to solve your problems. Now let’s get started with the Example.

To Make a React Native App

Getting started with React Native will help you to know more about the way you can make a React Native project. We are going to use react native command line interface to make our React Native App.

If you have previously installed a global react-native-cli package, please remove it as it may cause unexpected issues:

npm uninstall -g react-native-cli @react-native-community/cli

Run the following commands to create a new React Native project

npx react-native init ProjectName

If you want to start a new project with a specific React Native version, you can use the --version argument:

npx react-native init ProjectName --version X.XX.X

Note If the above command is failing, you may have old version of react-native or react-native-cli installed globally on your pc. Try uninstalling the cli and run the cli using npx.

This will make a project structure with an index file named App.js in your project directory.

Installation of Dependency

As I mentioned, to pick a file we are going to use react-native-document-picker which provides DocumentPicker component. To use react-native-document-picker we need to install it using the following commands

Open the terminal and jump into your project

cd ProjectName

Run the following command

npm install react-native-document-picker --save

Linking of Dependency

After the updation of React Native 0.60, they have introduced autolinking feature means we do not require to link the library but they have also mentioned that some libraries need linking and react-native-document-picker is one of those cases. So for that, we need to link the library using

react-native link react-native-document-picker

CocoaPods Installation

Now we need to install pods

cd ios && pod install && cd ..

Code for the File Upload in React Native

Open App.js in any code editor and replace the code with the following code

App.js

// Example to Pick and Upload files in React Native
// https://aboutreact.com/file-uploading-in-react-native/

// Import React
import React, { useState } from 'react';
// Import core components
import {
  StyleSheet,
  Text,
  View,
  TouchableOpacity
} from 'react-native';

// Import Document Picker
import DocumentPicker from 'react-native-document-picker';

const App = () => {
  const [singleFile, setSingleFile] = useState(null);

  const uploadImage = async () => {
    // Check if any file is selected or not
    if (singleFile != null) {
      // If file selected then create FormData
      const fileToUpload = singleFile;
      const data = new FormData();
      data.append('name', 'Image Upload');
      data.append('file_attachment', fileToUpload);
      // Please change file upload URL
      let res = await fetch(
        'http://localhost/upload.php',
        {
          method: 'post',
          body: data,
          headers: {
            'Content-Type': 'multipart/form-data; ',
          },
        }
      );
      let responseJson = await res.json();
      if (responseJson.status == 1) {
        alert('Upload Successful');
      }
    } else {
      // If no file selected the show alert
      alert('Please Select File first');
    }
  };

  const selectFile = async () => {
    // Opening Document Picker to select one file
    try {
      const res = await DocumentPicker.pick({
        // Provide which type of file you want user to pick
        type: [DocumentPicker.types.allFiles],
        // There can me more options as well
        // DocumentPicker.types.allFiles
        // DocumentPicker.types.images
        // DocumentPicker.types.plainText
        // DocumentPicker.types.audio
        // DocumentPicker.types.pdf
      });
      // Printing the log realted to the file
      console.log('res : ' + JSON.stringify(res));
      // Setting the state to show single file attributes
      setSingleFile(res);
    } catch (err) {
      setSingleFile(null);
      // Handling any exception (If any)
      if (DocumentPicker.isCancel(err)) {
        // If user canceled the document selection
        alert('Canceled');
      } else {
        // For Unknown Error
        alert('Unknown Error: ' + JSON.stringify(err));
        throw err;
      }
    }
  };
  return (
    <View style={styles.mainBody}>
      <View style={{ alignItems: 'center' }}>
        <Text style={{ fontSize: 30, textAlign: 'center' }}>
          React Native File Upload Example
        </Text>
        <Text
          style={{
            fontSize: 25,
            marginTop: 20,
            marginBottom: 30,
            textAlign: 'center',
          }}>
          www.aboutreact.com
        </Text>
      </View>
      {/*Showing the data of selected Single file*/}
      {singleFile != null ? (
        <Text style={styles.textStyle}>
          File Name: {singleFile.name ? singleFile.name : ''}
          {'\n'}
          Type: {singleFile.type ? singleFile.type : ''}
          {'\n'}
          File Size: {singleFile.size ? singleFile.size : ''}
          {'\n'}
          URI: {singleFile.uri ? singleFile.uri : ''}
          {'\n'}
        </Text>
      ) : null}
      <TouchableOpacity
        style={styles.buttonStyle}
        activeOpacity={0.5}
        onPress={selectFile}>
        <Text style={styles.buttonTextStyle}>Select File</Text>
      </TouchableOpacity>
      <TouchableOpacity
        style={styles.buttonStyle}
        activeOpacity={0.5}
        onPress={uploadImage}>
        <Text style={styles.buttonTextStyle}>Upload File</Text>
      </TouchableOpacity>
    </View>
  );
};

const styles = StyleSheet.create({
  mainBody: {
    flex: 1,
    justifyContent: 'center',
    padding: 20,
  },
  buttonStyle: {
    backgroundColor: '#307ecc',
    borderWidth: 0,
    color: '#FFFFFF',
    borderColor: '#307ecc',
    height: 40,
    alignItems: 'center',
    borderRadius: 30,
    marginLeft: 35,
    marginRight: 35,
    marginTop: 15,
  },
  buttonTextStyle: {
    color: '#FFFFFF',
    paddingVertical: 10,
    fontSize: 16,
  },
  textStyle: {
    backgroundColor: '#fff',
    fontSize: 15,
    marginTop: 16,
    marginLeft: 35,
    marginRight: 35,
    textAlign: 'center',
  },
});

export default App;

Server Side PHP Code

Please find the server-side PHP code below. You will need to set up a local server to use this Script.

Core PHP Code (upload.php)

<?php
  if(!empty($_FILES['file_attachment']['name']))
  {
    $target_dir = "uploads/";
    if (!file_exists($target_dir))
    {
      mkdir($target_dir, 0777);
    }
    $target_file =
      $target_dir . basename($_FILES["file_attachment"]["name"]);
    $imageFileType = 
      strtolower(pathinfo($target_file,PATHINFO_EXTENSION));
    // Check if file already exists
    if (file_exists($target_file)) {
      echo json_encode(
         array(
           "status" => 0,
           "data" => array()
           ,"msg" => "Sorry, file already exists."
         )
      );
      die();
    }
    // Check file size
    if ($_FILES["file_attachment"]["size"] > 50000000) {
      echo json_encode(
         array(
           "status" => 0,
           "data" => array(),
           "msg" => "Sorry, your file is too large."
         )
       );
      die();
    }
    if (
      move_uploaded_file(
        $_FILES["file_attachment"]["tmp_name"], $target_file
      )
    ) {
      echo json_encode(
        array(
          "status" => 1,
          "data" => array(),
          "msg" => "The file " . 
                   basename( $_FILES["file_attachment"]["name"]) .
                   " has been uploaded."));
    } else {
      echo json_encode(
        array(
          "status" => 0,
          "data" => array(),
          "msg" => "Sorry, there was an error uploading your file."
        )
      );
    }
  }
?>

PHP CodeIgniter Code

/*  Update Images*/
public function uploadImage() {	
  if(!empty($_FILES['file_attachment']['name'])) {
    $res        = array();
    $name       = 'file_attachment';
    $imagePath 	= 'assets/upload/file_attachment';
    $temp       = explode(".",$_FILES['file_attachment']['name']);
    $extension 	= end($temp);
    $filenew 	= str_replace(
                    $_FILES['file_attachment']['name'],
                    $name,
                    $_FILES['file_attachment']['name']) . 
                    '_' . time() . '' . "." . $extension;  		
    $config['file_name']   = $filenew;
    $config['upload_path'] = $imagePath;
    $this->upload->initialize($config);
    $this->upload->set_allowed_types('*');
    $this->upload->set_filename($config['upload_path'],$filenew);
    if(!$this->upload->do_upload('file_attachment')) {
      $data = array('msg' => $this->upload->display_errors());
    } else {
      $data = $this->upload->data();	
      if(!empty($data['file_name'])){
        $res['image_url'] = 'assets/upload/file_attachment/' .
                            $data['file_name']; 
      }
      if (!empty($res)) {
	echo json_encode(
          array(
            "status" => 1,
            "data" => array(),
            "msg" => "upload successfully",
            "base_url" => base_url(),
            "count" => "0"
          )
        );
      }else{
	echo json_encode(
          array(
            "status" => 1,
            "data" => array(),
            "msg" => "not found",
            "base_url" => base_url(),
            "count" => "0"
          )
        );
      }
    }
  }
}

To Run the React Native App

Open the terminal again and jump into your project using.

cd ProjectName

1. Start Metro Bundler

First, you will need to start Metro, the JavaScript bundler that ships with React Native. To start Metro bundler run following command

npx react-native start

Once you start Metro Bundler it will run forever on your terminal until you close it. Let Metro Bundler run in its own terminal. Open a new terminal and run the application.

2. Start React Native Application

To run the project on an Android Virtual Device or on real debugging device

npx react-native run-android

or on the iOS Simulator by running (macOS only)

npx react-native run-ios

Output Screenshots

File Upload 1         

This is how you can upload File/Image to Server with Form Data in React Native. If you have any doubts or you want to share something about the topic you can comment below or contact us here. There will be more posts coming soon. Stay tuned!

Hope you liked it. 🙂

6 thoughts on “How to Upload File/Image to Server with Form Data in React Native”

    • Hi,
      i have a problem:
      the procedure is all right but on, file .php create folder but NOT upload image!

      You can help me

      Reply

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.