DEV Community

Cover image for File upload with React & NodeJS
Damian Piwowarczyk
Damian Piwowarczyk

Posted on

File upload with React & NodeJS

Hi there,

Today I will briefly describe how to upload images/files from React front-end to NodeJS back-end using express and multer. I will omit all validations to keep it short & simple.
 
 

Frontend

 
We will use create react app as a boilerplate

mkdir imgUploadExample && cd imgUploadExample
npx install create-react-app frontend
Enter fullscreen mode Exit fullscreen mode

 
Once installation completed we should see App.js file in frontend folder.

We will start first with creating a simple form where we can upload our image.

return (
    <div className='App'>
      <h1>Upload to server</h1>
      {image.preview && <img src={image.preview} width='100' height='100' />}
      <hr></hr>
      <form onSubmit={handleSubmit}>
        <input type='file' name='file' onChange={handleFileChange}></input>
        <button type='submit'>Submit</button>
      </form>
      {status && <h4>{status}</h4>}
    </div>
  )
Enter fullscreen mode Exit fullscreen mode

 
We will need to create two functions

handleFileChange - triggered when file is uploaded, displays an image preview & stores our image data in the state.

handleSubmit - let us submit the image to the server.

 function App() {
  const [image, setImage] = useState({ preview: '', data: '' })
  const [status, setStatus] = useState('')
  const handleSubmit = async (e) => {
    e.preventDefault()
    let formData = new FormData()
    formData.append('file', image.data)
    const response = await fetch('http://localhost:5000/image', {
      method: 'POST',
      body: formData,
    })
    if (response) setStatus(response.statusText)
  }

  const handleFileChange = (e) => {
    const img = {
      preview: URL.createObjectURL(e.target.files[0]),
      data: e.target.files[0],
    }
    setImage(img)
  }
Enter fullscreen mode Exit fullscreen mode

Once we start react app with npm run start we should see form with select & submit button.

Alt text

Backend

Now we going to create node application that will handle our POST request with image data send from the fronted. Once image is received it will save it our working directory.

To create new directory run command

mkdir backend && cd backend && mkdir images
Enter fullscreen mode Exit fullscreen mode

then we initialize our application with npm init

We will install few required packages by running command

npm install express cors multer
Enter fullscreen mode Exit fullscreen mode

Our working directories should look like this

├── backend
│   ├── app.js
│   ├── node_modules
|   ├── images
│   ├── package.json
│   └── package-lock.json
└── frontend
    ├── node_modules
    ├── package.json
    ├── public
    ├── README.md
    ├── src
    └── yarn.lock
Enter fullscreen mode Exit fullscreen mode

Multer is a middleware that will let us handle multipart/form data sent from our frontend form.

Cors will let us accept cross origin request from our frontend to backend.

const express = require('express')
const app = express()
const port = 5000
const cors = require('cors')
const multer = require('multer')

const storage = multer.diskStorage({
  destination: (req, file, cb) => {
    cb(null, 'images/')
  },
  filename: (req, file, cb) => {
    cb(null, file.originalname)
  },
})

const upload = multer({ storage: storage })

app.use(cors())

app.post('/image', upload.single('file'), function (req, res) {
  res.json({})
})

app.listen(port, () => {
  console.log(`listening at http://localhost:${port}`)
})

Enter fullscreen mode Exit fullscreen mode

We initialized multer storage, now received images will be stored at backend/images with original filename.

Start backend with

 node app.js
Enter fullscreen mode Exit fullscreen mode

Go to the frontend & upload an image.

Alt text

Thanks for reading hope someone will find it useful :)

Github repo

Oldest comments (1)

Collapse
 
javadsh profile image
javad-sh

hello friend.
how can I set the file name from client side?
I tried to send it as formdata child.
But I couldn't get it in backend in storage cb req.body .