如何在React中通过用户自定义输入实现图片上传并解决预览与传参问题
React图片上传功能问题解决方案
1 图片无法在img标签正常加载问题修复
- 错误原因:代码中img标签使用了非标准的
url属性,HTML原生img标签加载图片的指定属性为src - 优化补充:新增非空判断避免未选文件时出现裂图,新增临时链接销毁逻辑避免内存泄漏
2 后端传参逻辑优化
- 错误原因:当前传给后端的
file是本地临时生成的blob链接,仅在当前浏览器会话有效,后端无法解析获取真实图片资源;直接把文件对象塞入JSON对象会触发序列化异常 - 解决方案:使用
FormData封装所有请求参数,不需要调整原有name/date/title等字段的结构,仅新增文件字段即可,请求自动转为multipart/form-data格式,后端按常规表单字段接收即可,几乎不增加逻辑复杂度
修正后完整代码
import React, { useState, useEffect } from "react"; import { Link } from "react-router-dom"; import Axios from 'axios'; export default function PostJournalEntry(){ /* Hooks */ const [selectedFile, setSelectedFile] = useState(null); const [filePreviewUrl, setFilePreviewUrl] = useState(""); const [title, setTitle] = useState(""); const [journalEntry, setJournalEntry] = useState(""); /* End of Hooks */ // 组件卸载时释放blob临时链接,避免内存泄漏 useEffect(() => { return () => { if (filePreviewUrl) URL.revokeObjectURL(filePreviewUrl); } }, [filePreviewUrl]) /* Click Handlers */ const handleTitle = (e)=>{ setTitle(e.target.value) } const handleJournalEntry = (e)=>{ setJournalEntry(e.target.value) } const handleFile = (e)=>{ const fileObject = e.target.files[0] if (!fileObject) return const previewUrl = URL.createObjectURL(fileObject) setSelectedFile(fileObject) setFilePreviewUrl(previewUrl) } const postData = () =>{ // 用FormData封装所有参数,无需调整原有字段结构 const formData = new FormData() const dateTime = new Date().toLocaleString('en-GB') formData.append("name", "Anonymus") formData.append("title", title) formData.append("journalEntry", journalEntry) formData.append("date", dateTime) // 仅新增文件字段 if (selectedFile) formData.append("file", selectedFile) Axios.post("http://localhost:5000/post", formData, { headers: { 'Content-Type': 'multipart/form-data' } }).then((response)=>{ alert("Journal Entry Submitted!") console.log("Post Data", response.data) // 提交成功后清理临时链接 URL.revokeObjectURL(filePreviewUrl) setSelectedFile(null) setFilePreviewUrl("") }) .catch((error)=>{console.log(error)}) } /* End of Click Handlers */ return( <main className ="post__main"> <form onSubmit={(e)=>{e.preventDefault()}} className = "post__form"> <input onChange={handleFile} type = "file" accept="image/*"/> <input onChange={handleTitle} type = "text" placeholder= "Title" value={title}/> <input onChange={handleJournalEntry}type = "text" placeholder = "Journal Entry" value={journalEntry}/> <button onClick = {postData} className = "form__button">Submit Entry</button> {/* 修正img属性为src,新增非空判断 */} {filePreviewUrl && <img className="post__image" src={filePreviewUrl} alt="Preview"/>} </form> <Link to = "/">Back to HomePage</Link> </main> ) }
内容的提问来源于stack exchange,提问作者Brute
相关产品推荐
相关产品推荐

