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.

We will use FormData to upload the file on the server. I prefer not to include third-party dependencies unless it’s absolutely necessary.

Why use FormData for File Uploading in React Native?

When searching for file uploading examples in React Native, you will find many examples that use external third-party dependencies. However, I prefer to avoid them and find alternative solutions. One solution is to use FormData. 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 other people’s 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 FormData 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');
        }
    };

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’re having trouble with the file picker, there’s an example of how to use the file picker in React Native that can help you solve your issues. 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 havean 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 create 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 update of React Native 0.60, they have introduced autolinking feature. This means we do not require linking 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 thetopic,c 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.