You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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;
关键修正说明
  1. 传递提交回调:CreateAlbum组件通过onSubmit props将处理POST请求的逻辑传递给AlbumForm,确保表单提交时能触发正确的业务逻辑。
  2. 正确使用react-hook-form:handleSubmit(onSubmit)是react-hook-form的标准用法——先验证表单,验证通过后调用传入的onSubmit函数,并自动传入验证后的表单数据。
  3. 修复Props接收:AlbumForm改为解构props,明确接收onSubmit和initialData,避免混淆props对象和实际数据。
  4. 移除循环引用:删除AlbumForm中不必要的CreateAlbum导入,解决循环引用问题。
  5. 完善错误处理:在fetch调用中添加catch分支捕获网络异常,同时给表单字段添加错误提示,提升用户体验。

内容的提问来源于stack exchange,提问作者Tho

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 04:02:04