How to Upload Images from React Native
Tags: reactnative, mobiledevelopment
Published: 2021-02-24 16:42:06

---
title: How to Upload Images from React Native
published: true
description: A high level look into uploading images from React Native to a remote server.
tags: reactnative, mobiledevelopment
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bpksn2mfs7868l79xoq0.jpeg
canonical_url: https://www.reactnativeschool.com/how-to-upload-images-from-react-native
---


In this tutorial we'll cover how to upload an image from a React Native app to a remote server.

> This is just a high level overview. If you want details (upload progress, setting up a server, multiple images, etc.) please check out our class on [Uploading Images in React Native](https://www.reactnativeschool.com/uploading-images-in-react-native/).

With that said, let's get into it.

## Tools

- [react-native-image-picker](https://github.com/react-native-image-picker/react-native-image-picker). Allows us to access the library of images or the camera.
- [Express](https://expressjs.com/) + [multer](https://github.com/expressjs/multer#readme): Create a server that can accept image uploads. However you setup the backend the process will be extremely similar.

## The Code

Explanation of code below.

```jsx
// server.js

const express = require('express');
const multer = require('multer');
const bodyParser = require('body-parser');

const app = express();
app.use(bodyParser.json());

const storage = multer.diskStorage({
  destination(req, file, callback) {
    callback(null, './images');
  },
  filename(req, file, callback) {
    callback(null, `${file.fieldname}_${Date.now()}_${file.originalname}`);
  },
});

const upload = multer({ storage });

app.get('/', (req, res) => {
  res.status(200).send('You can post to /api/upload.');
});

app.post('/api/upload', upload.array('photo', 3), (req, res) => {
  console.log('file', req.files);
  console.log('body', req.body);
  res.status(200).json({
    message: 'success!',
  });
});

app.listen(process.env.PORT || 3000, () => {
  console.log(
    `server is running at http://localhost:${process.env.PORT || 3000}`
  );
});
```

```jsx
// App.js

import React from 'react';
import { View, Image, Button, Platform } from 'react-native';
import { launchImageLibrary } from 'react-native-image-picker';

const SERVER_URL = 'http://localhost:3000';

const createFormData = (photo, body = {}) => {
  const data = new FormData();

  data.append('photo', {
    name: photo.fileName,
    type: photo.type,
    uri: Platform.OS === 'ios' ? photo.uri.replace('file://', '') : photo.uri,
  });

  Object.keys(body).forEach((key) => {
    data.append(key, body[key]);
  });

  return data;
};

const App = () => {
  const [photo, setPhoto] = React.useState(null);

  const handleChoosePhoto = () => {
    launchImageLibrary({ noData: true }, (response) => {
      // console.log(response);
      if (response) {
        setPhoto(response);
      }
    });
  };

  const handleUploadPhoto = () => {
    fetch(`${SERVER_URL}/api/upload`, {
      method: 'POST',
      body: createFormData(photo, { userId: '123' }),
    })
      .then((response) => response.json())
      .then((response) => {
        console.log('response', response);
      })
      .catch((error) => {
        console.log('error', error);
      });
  };

  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      {photo && (
        <>
          <Image
            source={{ uri: photo.uri }}
            style={{ width: 300, height: 300 }}
          />
          <Button title="Upload Photo" onPress={handleUploadPhoto} />
        </>
      )}
      <Button title="Choose Photo" onPress={handleChoosePhoto} />
    </View>
  );
};

export default App;
```

## Explanation - server.js

The server sets the ground work for what we're doing so let's talk about that first. It's a standard Express server but our `/api/upload` path uses the Multer middleware and accepts `multipart/form-data`. If it sees a `name` with `photo` it's going to handle the image upload.

You can check out the multer documentation for details on how it's configured but this will just write files locally to the `images/` directory.

The file(s) that were uploaded will be available at `request.files` and any other data passed will be available at `request.body`.

## Explanation - App.js

Let's look at the `handleChoosePhoto` function first. In it we open the image library and when a user selects an image we store that in state.

Next is `handleUploadPhoto`. In it we set up a standard fetch request and set the method to `POST`, which will call the `/api/post` route we defined in the server.

What's different is how we pass data in the `body` field.

If you're anything like me you're used to simply stringifying some JSON (`JSON.stringify({ example: true })`) and calling it done.

To handle image uploads we need to set the encoding type to `multipart/form-data` which means we need to format our data differently.

Thus the `createFormData` function. This function will go ahead and take the image we selected and add it to the `photo` field of the form data with the required info.

It will also take any other data you want to pass to it and add it to the form data, as you can see from the `userId`.

With this the file will be available at `request.files` and the userId will be available at `request.body.userId`.

> **Important Note:** Notice that ternary operator in the `uri` field? We have to do that because iOS prepends the path it returns with a `file://` that I've found breaks file uploads so we remove it.

## Conclusion

This was a _super_ brief overview of a relatively complex subject. The reality is that uploading an image takes more time than a small JSON object and on mobile networks we have unique challenges to deal with such as:

- Slow networks
- No network connection
- Network connections stopping & starting during upload

These aren't exceptions - they're guarantees that we have to deal with. That's why we cover them in the [Uploading Images in React Native class](https://www.reactnativeschool.com/uploading-images-in-react-native/) here on React Native School.

If you're interested in going deeper on this subject (or any of the others we cover in our classes) become a member!