React onSubmit e.preventDefault() 有时不起作用 + Axios

React onSubmit e.preventDefault() not working sometimes + Axios

现在我在 React 中遇到了这个奇怪的问题,其中带有 e.preventDefault() 的 onSubmit 函数有时会避免刷新页面,有时则不会。

我创建了两个挂钩来跟踪上传的文件及其进度条。

const [ uploadedFiles, setUploadedFiles ] = useState([]);
const [ uploadPercentages, setUploadPercentages ] = useState([]);

onSubmit函数使用axios向后台发起请求

const onSubmit = async e => {
        e.preventDefault();

        if(!!file) {
            // Show file box on screen
            let index = addUpload(file);

            const formData = new FormData();
            formData.append("file", file);

            try {
                await axios.post("/upload_video", formData, {
                    onUploadProgress: progressEvent => {
                        const { loaded, total } = progressEvent;
                        let progress = uploadPercentages.concat(0)
                        progress[index] = Math.round((loaded * 100) / total)

                        setUploadPercentages(progress);
                    }
                })
            } catch(err) {
                // Handlers
            }
        }
        return false // trying something different to avoid refresh
}

以防万一,addUpload 函数与问题的来源几乎没有关系。我把它拿走进行测试,一切都一样。

如果有人能提供帮助,我将不胜感激。

编辑:

这是表格。

<form className="choose-file" onSubmit={onSubmit}> 
            
     <div className="file-container">
         { file ?
             <p> { file.name } </p>
             :
             <label className="file-label" htmlFor="customFile">
                 <input type="file" className="file-input" id="customFile" onChange={ onChange }/>
                 <p><i className="fas fa-cloud-upload-alt"></i></p>
                 <p>Click here to select file</p>
             </label>   
          }
     </div>

     <div className="file-options">
          <input type="submit" value="Upload" className="file-input" id="customFile"/>
          <button type="button" onClick={ removeFile }>Delete</button>
     </div>

</form>

“文件”是第三个挂钩,用于向用户显示他们刚刚选择的文件的名称。

编辑 2:

问题似乎只在文件大小大于 100MB 时出现。此外,一旦出现问题,无论大小,每个文件都会出现。

例如,如果我上传一个 7MB 的文件,页面不会刷新,如果我然后尝试一个 100MB 的文件,它会开始刷新每个即将到来的文件,并且再也不会看到 axios post 之后的所有控制台日志。

编辑 3:

因为我是 运行 Flask 的本地后端,所以我尝试断开它与 React 应用程序的连接,看看会发生什么。对于小文件,只向后端请求一次,并触发 catch(err) 中的警报。对于大文件,该请求被询问了大约四次,但从未到达捕获部分。

发送帮助

我想问题不在于 addUpload 而在于 async。你可以这样试试

const onSubmit = (e) => {
 e.preventDefault();
 
 // After collecting formData ... 
 // in the *try* block do this
 
 const post = axios.post("/upload_video", formData, {
                    onUploadProgress: progressEvent => {
                        const { loaded, total } = progressEvent;
                        let progress = uploadPercentages.concat(0)
                        progress[index] = Math.round((loaded * 100) / total)

                        setUploadPercentages(progress);
                    }
  
  post.then(() => {alert('Done posting')}) // inside this you can do whatever you want to do after axios.post 
}

**编辑:**

鉴于您在评论中提到该解决方案不起作用,这里有一个替代方案。

声明一个新函数

const async post = () => {
 // Get the formData here

 await axios.post("/upload_video", formData, {
                    onUploadProgress: progressEvent => {
                        const { loaded, total } = progressEvent;
                        let progress = uploadPercentages.concat(0)
                        progress[index] = Math.round((loaded * 100) / total)

                        setUploadPercentages(progress);
                    }
}

// Now in the onSubmit function

const onSubmit =  (e) => {
 
 e.preventDefalut();
 post()
}

这是我的最终解决方案。希望这有效...

我一直面临使用箭头函数作为 HANDLERS 的问题, 试着把它变成正常功能

async function HandelOnSubmit (e) {
        e.preventDefault();

        if(!!file) {
            // Show file box on screen
            let index = addUpload(file);

            const formData = new FormData();
            formData.append("file", file);

            try {
                await axios.post("/upload_video", formData, {
                    onUploadProgress: progressEvent => {
                        const { loaded, total } = progressEvent;
                        let progress = uploadPercentages.concat(0)
                        progress[index] = Math.round((loaded * 100) / total)

                        setUploadPercentages(progress);
                    }
                })
            } catch(err) {
                // Handlers
            }
        }
        return false // trying something different to avoid refresh }

最后,问题变成了将文件保存在 React 的 public 文件夹中这样简单的问题。

我的猜测是,每次在此文件夹中检测到更改时,这都会导致整个项目刷新。对于小对象几乎为零,但是对于大文件则需要一段时间,导致组件刷新。