React表单提交未等待API返回,无法更新生成图片状态
表单提交未等待API返回,无法更新生成图片状态
问题描述
我有一个表单提交处理函数,用于接收用户上传的图片,将其发送至后端处理后,后端会返回Base64格式的修改后图片,前端需展示该图片。目前图片的收发流程正常,但前端组件的处理函数未等待API返回结果,导致无法将返回的图片数据设置到组件状态中。
组件代码(包含表单与处理函数)
function Workshop() { // 用于存储和更新前端数据 const [imageUpload, setImageUpload] = useState(); const [imageGenerated, setImageGenerated] = useState(); // 处理表单提交 const handleSubmit = event => { event.preventDefault(); // 将用户图片追加到formData对象 setImageUpload(event.target.files[0]); const formData = new FormData(); formData.append("file", imageUpload); // 调用前端API处理图片 if(imageUpload) { const res = frontAPI.callGenerateImage(formData); console.log("back to front"); // ### 此处未等待API返回 ### console.log(res); // ### 此处未等待API返回 ### setImageGenerated(res); // ### 此处未等待API返回 ### } }; return ( <> <div className="workshop"> <form method="post" onSubmit={handleSubmit} encType="multipart/form-data"> <input type="file" name="imageUploader" onChange={handleImagePreview} /> <img alt="preview image" src={imagePreview} /> <button type="submit">Modify Image</button> </form> <img alt="generated image" src={"data:image/jpeg;base64," + imageGenerated} /> </div> </> ); } export default Workshop;
前端API代码(包含Fetch)
export function callGenerateImage(formData) { var base64; fetch("/generator", { method: "POST", body: formData }) .then(data => data.json()) .then(res => { base64 = Buffer.from(res.data, "binary" ).toString("base64"); console.log(base64); // 此处能正常输出Base64字符串 return base64; }) };
问题分析
从输出可见,后端返回的Base64图片数据已正常接收,但const res = frontAPI.callGenerateImage(formData);未等待Fetch的返回结果就继续执行后续代码。曾尝试将API函数改为async函数,并将该行改为const res = await frontAPI.callGenerateImage(formData);,但未生效。
解决方案
1. 修正API函数,确保返回Promise
API函数需要返回完整的Promise链,否则无法被await等待:
// 方案一:使用async/await重写API函数 export async function callGenerateImage(formData) { const response = await fetch("/generator", { method: "POST", body: formData }); const res = await response.json(); return Buffer.from(res.data, "binary").toString("base64"); } // 方案二:保留链式调用,直接返回Promise export function callGenerateImage(formData) { return fetch("/generator", { method: "POST", body: formData }) .then(data => data.json()) .then(res => Buffer.from(res.data, "binary").toString("base64")); };
2. 将组件提交函数改为异步函数
事件处理函数可以直接定义为async函数,使用await等待API返回结果,同时修正原代码中setState异步导致的取值错误:
const handleSubmit = async event => { event.preventDefault(); // 直接获取文件,避免setState异步带来的旧值问题 const file = event.target.files[0]; const formData = new FormData(); formData.append("file", file); if(file) { const res = await frontAPI.callGenerateImage(formData); setImageGenerated(res); } };
关键说明
- 组件内的事件处理函数支持定义为
async函数,不存在“非顶层不能用”的限制,之前尝试无效是因为API函数未正确返回Promise。 useState的更新是异步操作,不能在调用setImageUpload后立刻使用imageUpload变量,直接取event.target.files[0]是更可靠的方式。
内容的提问来源于stack exchange,提问作者Gnougnou
相关产品推荐
相关产品推荐

