如何在发送前修改FormData?实现图片转Base64并在子组件复用
解决方案:表单提交前修改FormData并将图片转为Base64
原代码核心问题
- 文件输入框
name属性错误设置为title,导致FormData中无法获取到file字段 - 仅在文件选择时转换Base64,但未将编码值存入提交的FormData,默认表单提交仍会使用原始文件(或因name错误导致字段缺失)
- React Router的
Form组件默认自动提交,无法拦截并修改FormData
一、修改AddForm组件:自定义表单提交逻辑
通过拦截表单提交事件,手动构造并修改FormData,同时存储Base64编码的图片数据:
import { Form, useNavigation } from 'react-router-dom'; import { useState } from 'react'; import classes from './AuthForm.module.css'; function AddForm() { const navigation = useNavigation(); const isSubmitting = navigation.state === 'submitting'; const [base64Image, setBase64Image] = useState(''); // 图片转Base64工具函数 function fileToBase64(file) { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.readAsDataURL(file); reader.onload = () => resolve(reader.result); reader.onerror = (error) => reject(error); }); } // 处理文件选择,转换并存储Base64 async function handleFileInputChange(event) { const file = event.target.files[0]; if (!file) return; try { const base64 = await fileToBase64(file); setBase64Image(base64); } catch (error) { console.error('图片转Base64失败:', error); } } // 拦截表单提交,修改FormData后手动发送 async function handleSubmit(event) { event.preventDefault(); const formElement = event.target; const formData = new FormData(formElement); // 替换原始文件为Base64编码值 if (base64Image) { formData.delete('file'); formData.append('file', base64Image); } // 使用fetch发送自定义FormData await fetch(formElement.action, { method: formElement.method, body: formData, }); // 提交后重置表单和状态 formElement.reset(); setBase64Image(''); } return ( <> <Form method="post" className={classes.form} onSubmit={handleSubmit}> <div> <label htmlFor="title">Tytuł:</label> <input type="text" id="title" name='title' required /> </div> <div> <label htmlFor="file">Wybierz plik:</label> <input type="file" id="file" name='file' {/* 修正name属性为file */} onChange={handleFileInputChange} accept="image/*" {/* 可选:限制仅上传图片 */} /> </div> <button disabled={isSubmitting}> {isSubmitting ? 'Adding...' : 'Add'} </button> </Form> </> ); } export default AddForm;
二、修正AddPage的action函数
修正拼写错误,并确保能正确获取Base64数据:
import AddForm from '../components/AddForm'; function AddPage() { return <AddForm/>; } export default AddPage; export async function action({ request }) { const data = await request.formData(); console.log('FormData内容:', data); const postData = { title: data.get('title'), // 修正拼写错误:titlt -> title file: data.get('file'), // 现在可获取到Base64编码的图片 }; console.log('处理后的提交数据:', postData); // 此处可添加发送到后端的逻辑,例如: // await fetch('/api/posts', { // method: 'POST', // headers: { 'Content-Type': 'application/json' }, // body: JSON.stringify(postData) // }); return null; }
关键说明
- 修改FormData时机:在
handleSubmit中阻止默认提交,手动构造FormData并修改字段,确保提交的是自定义后的数据 - Base64传递:通过
useState存储编码后的图片,提交时替换FormData中的原始文件字段 - 字段一致性:文件输入框的
name属性必须与action中获取数据的key(file)保持一致,否则会出现字段为null的情况
内容的提问来源于stack exchange,提问作者Rolegur
相关产品推荐
相关产品推荐

