Frontend:

import React, { useState } from "react";

function ImageUpload() {

  const [image, setImage] = useState(null);

  // Select Image
  const handleImage = (e) => {
    setImage(e.target.files[0]);
  };

  // Upload Image
  const handleUpload = async () => {

    const formData = new FormData();

    formData.append("image", image);

    try {

      const response = await fetch(
        "http://localhost:5000/upload",
        {
          method: "POST",
          body: formData,
        }
      );

      const data = await response.json();

      console.log(data);

      alert("Image Uploaded");

    } catch (error) {

      console.log(error);

    }
  };

  return (
    <div>

      <h2>React Image Upload</h2>

      <input
        type="file"
        onChange={handleImage}
      />

      <button onClick={handleUpload}>
        Upload
      </button>

    </div>
  );
}

export default ImageUpload;

Backend:

npm install express multer cors
const express = require("express");
const multer = require("multer");
const cors = require("cors");

const app = express();

app.use(cors());

// Storage
const storage = multer.diskStorage({

  destination: function (req, file, cb) {
    cb(null, "uploads/");
  },

  filename: function (req, file, cb) {
    cb(null, Date.now() + "-" + file.originalname);
  },

});

const upload = multer({ storage });

// Upload API
app.post(
  "/upload",
  upload.single("image"),
  (req, res) => {

    res.json({
      message: "Image Uploaded",
      file: req.file,
    });

  }
);

app.listen(5000, () => {
  console.log("Server Running");
});