React表单POST数据到API报错:onSubmit未定义/onValid非函数
问题描述
尝试将React表单中的数据POST到API,为此创建了两个独立组件,但每次点击提交按钮时,都会出现“onSubmit is not defined”或“onValid is not a function”的错误。尝试替换<form onSubmit={handleSubmit(album)}>为<form onSubmit={handleSubmit(onSubmit)}>或<form onSubmit={handleSubmit}>,均无法解决问题。
原组件代码如下:
createAlbum.js
import AlbumForm from "./AlbumForm"; import { useNavigate } from "react-router-dom"; import React, { useState } from 'react'; const endpoint = `${process.env.REACT_APP_API_URL}/api/album/`; function CreateAlbum(){ const navigate = useNavigate(); const handleSubmit = (newAlbum) => { const request = fetch(endpoint, { method: 'POST', body: JSON.stringify(newAlbum), headers: {"Content-Type": "application/json"} }); request.then((response) => { if(!response.ok) { console.error(response.statusText); } else { navigate("/"); } }) }; return( <AlbumForm /> ); } export default CreateAlbum;
AlbumForm.js
import { Card, CardContent, TextField } from "@mui/material"; import { useForm } from "react-hook-form"; import { Controller } from "react-hook-form"; import React, { useState } from 'react'; import CreateAlbum from "./createAlbum"; function AlbumForm(album){ const { handleSubmit, control } = useForm({ defaultValues: album ? album : { name: "", artist: "", imageUrl: "", }, }); return( <form onSubmit={handleSubmit(album)}> <Card> <CardContent> <Controller name="name" control={control} rules={{ required: true }} render={({ field }) => ( <TextField label="name" variant="outlined" {...field} margin="normal" fullWidth /> )} margin="normal" /> </CardContent> </Card> <button type="submit" >submit</button> </form> ) } export default AlbumForm;
错误原因
- 提交回调未传递:CreateAlbum组件中定义了处理POST请求的
handleSubmit函数,但并未通过props将其传递给AlbumForm组件,导致AlbumForm的表单提交时无法找到正确的处理逻辑。 - Props处理错误:AlbumForm的参数是props对象,直接将参数命名为
album会拿到整个props集合;同时错误地将这个album(props)传给handleSubmit——react-hook-form的handleSubmit需要接收的是表单验证成功后的回调函数,而非数据对象。 - 循环引用问题:AlbumForm组件中不必要地导入了CreateAlbum组件,造成循环引用,可能引发额外的运行时错误。
修正后的代码
createAlbum.js
import AlbumForm from "./AlbumForm"; import { useNavigate } from "react-router-dom"; import React from 'react'; const endpoint = `${process.env.REACT_APP_API_URL}/api/album/`; function CreateAlbum(){ const navigate = useNavigate(); const handleSubmit = (newAlbum) => { fetch(endpoint, { method: 'POST', body: JSON.stringify(newAlbum), headers: {"Content-Type": "application/json"} }) .then((response) => { if(!response.ok) { throw new Error(response.statusText); } navigate("/"); }) .catch(error => { console.error("提交失败:", error); }); }; return( <AlbumForm onSubmit={handleSubmit} /> ); } export default CreateAlbum;
AlbumForm.js
import { Card, CardContent, TextField, Button } from "@mui/material"; import { useForm, Controller } from "react-hook-form"; import React from 'react'; function AlbumForm({ onSubmit, initialData }) { const { handleSubmit, control } = useForm({ defaultValues: initialData || { name: "", artist: "", imageUrl: "", }, }); return( <form onSubmit={handleSubmit(onSubmit)}> <Card> <CardContent> <Controller name="name" control={control} rules={{ required: "专辑名称不能为空" }} render={({ field, fieldState: { error } }) => ( <TextField label="专辑名称" variant="outlined" {...field} margin="normal" fullWidth error={!!error} helperText={error?.message} /> )} /> <Controller name="artist" control={control} rules={{ required: "艺术家名称不能为空" }} render={({ field, fieldState: { error } }) => ( <TextField label="艺术家" variant="outlined" {...field} margin="normal" fullWidth error={!!error} helperText={error?.message} /> )} /> <Controller name="imageUrl" control={control} render={({ field }) => ( <TextField label="封面图片URL" variant="outlined" {...field} margin="normal" fullWidth /> )} /> </CardContent> </Card> <Button type="submit" variant="contained" color="primary" style={{ marginTop: 16 }} > 提交 </Button> </form> ) } export default AlbumForm;
关键修正说明
- 传递提交回调:CreateAlbum组件通过
onSubmitprops将处理POST请求的逻辑传递给AlbumForm,确保表单提交时能触发正确的业务逻辑。 - 正确使用react-hook-form:
handleSubmit(onSubmit)是react-hook-form的标准用法——先验证表单,验证通过后调用传入的onSubmit函数,并自动传入验证后的表单数据。 - 修复Props接收:AlbumForm改为解构props,明确接收
onSubmit和initialData,避免混淆props对象和实际数据。 - 移除循环引用:删除AlbumForm中不必要的CreateAlbum导入,解决循环引用问题。
- 完善错误处理:在fetch调用中添加
catch分支捕获网络异常,同时给表单字段添加错误提示,提升用户体验。
内容的提问来源于stack exchange,提问作者Tho
相关产品推荐
相关产品推荐

