'File upload with multer refreshes React app

Update

This is happening because of hot-reloading comes with Creact React App. Related issues: https://github.com/expressjs/multer/issues/566

https://github.com/facebook/create-react-app/issues/4095


I am trying to learn file upload with Nodejs, Express, Multer and React for frontend. I achieved to upload files. There is a problem I struggle, not always but most of the time the whole app refreshes after upload. Here is the relevant code.

My simple form

<form onSubmit={this.handleFormSubmit}>
                <input
                    type="file"
                    id="file"
                    onChange={this.handleFileChange}
                />
            <button type="submit">Submit</button>
        </form>

handleFileChange and handleFormSubmit

handleFormSubmit = () => {
    const formData = new FormData();
    formData.append( "file", this.state.file );
    axios.post( "/api/upload", formData );
}

handleFileChange = ( e ) => {
    this.setState( { file: e.target.files[ 0 ] } );
}

Related express route code

const express = require( "express" );
const multer = require( "multer" );
const storage = multer.diskStorage( {
    destination( req, file, cb ) {
        cb( null, "client/public/images" );
    },
    filename( req, file, cb ) {
        cb( null, `${ Date.now() }-${ file.originalname }` );
    },
} );

const upload = multer( { storage } );

router.post( "/upload", upload.single( "file" ), ( req, res ) => {
    res.send();
} );

I searched a little bit but not luck. I've seen this post. Before seeing this I had already tried event.preventDefault(). Also, I've tried many things like uploading directly with onChange() without setting a state then handling it with onSubmit(). Before simplifying the code (like posting directly in handleFormSubmit) I was trying to do this via Redux actions but for debugging purposes I moved it here.



Solution 1:[1]

It is the first example here.

handleFormSubmit = async (e) => {
    e.preventDefault() // <-- missing this
    const formData = new FormData();
    formData.append( "file", this.state.file );
    const response = await axios.post( "/api/upload", formData );
}

handleFileChange = ( e ) => {
    this.setState( { file: e.target.files[ 0 ] } );
}

Solution 2:[2]

This is happening because of hot-reloading comes with Creact React App.

I ran into this issue too, but using plain webpack without CRA. I was uploading the files to a static dir served by webpack-dev-server. I fixed it by setting devServer.static.watch to false (webpack docs).

Solution 3:[3]

your are using

<button type="submit">Submit</button>

this is why refreshing

so do it like this

<button onClick={this.handleFormSubmit}>Submit</button>

Solution 4:[4]

remove this from multer

    destination( req, file, cb ) {
     cb( null, "client/public/images" );
    },

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Cisco
Solution 2 Jared
Solution 3
Solution 4 Aditya Joshi