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

使用Formik的handleSubmit时提示onSubmit is not a function错误求助

解决Formik提交时TypeError: onSubmit is not a function错误

问题描述

已解决应用中登录与注册组件的400 POST错误,但点击提交按钮时触发新报错:

Formik.tsx:824 Warning: An unhandled error was caught from submitForm() TypeError: onSubmit is not a function

登录与注册组件代码结构基本一致,以下是注册组件及CRUD.js中createUsuario函数的代码,已知有同类问题解决方案但不知如何套用,怀疑与ValidationSchema有关,寻求帮助。

注册组件原代码

import React from "react";
import { View, TextInput, TouchableOpacity,Text } from "react-native";
import { Formik, Form, Field, ErrorMessage } from 'formik';
import * as Yup from 'yup';
import {createUsuario} from '../../CRUD';

const SignupSchema = Yup.object().shape({
    email: Yup.string().email('El email ingresado no es valido.').required('Por favor ingrese su email.'),
    contrasenia: Yup.string()
      .min(6, 'La contrasenia es muy corta.')
      .max(20, 'La contrasenia es demasiado larga.')
      .required('Por favor ingrese su contrasenia.')
  });

export default function RegisterForm () {
    return(
    <Formik initialValues={{
        email: '',
        contrasenia: ''
    }}
    validationSchema={SignupSchema}
    handleSubmit={(values=>(createUsuario()))}>
        {({values,errors,touched, handleChange, setFieldTouched, isValid, handleSubmit}) =>(
        <View>
            <TextInput 
            placeholder="Email" 
            value={values.email} 
            onChangeText={handleChange('email')}
            onBlur={()=> setFieldTouched('email')}/>
            {touched.email && errors.email && (
                <Text>{errors.email}</Text>
            )}
            <TextInput 
            placeholder="Contraseña" 
            value={values.contrasenia} 
            onChangeText={handleChange('contrasenia')}
            onBlur={()=> setFieldTouched('contrasenia')}
            secureTextEntry={true}/>      
            {touched.contrasenia && errors.contrasenia && (
                <Text>{errors.contrasenia}</Text>
            )}
            <TouchableOpacity disabled={!isValid} style={{backgroundColor: isValid? '#289D8C': '#808080'}} onPress={handleSubmit}>
                <Text>Registrate</Text>
                </TouchableOpacity>
                </View>
                )}
    </Formik>
    )
}

CRUD.js中createUsuario函数原代码

export async function createUsuario(db,email, contrasenia){
    await setDoc(doc(db, "Usuario"), {
        email: email,
        contrasenia: contrasenia
      }).then(()=> {
        console.log("Guardado exitosamente");
      }).catch((error)=>{
        console.log("Hubo fallos al guardar");
      })
}

错误原因分析

  1. Formik属性名错误:Formik组件上使用了handleSubmit属性,但Formik要求提交逻辑必须通过onSubmit属性定义,这是触发onSubmit is not a function的直接原因。
  2. createUsuario参数缺失:createUsuario需要db、email、contrasenia三个参数,但原代码调用时未传递任何参数,会导致后续数据库操作失败。
  3. ValidationSchema无问题:Yup校验规则逻辑正确,与当前报错无关,无需怀疑这部分代码。

修复方案

步骤1:修正Formik提交属性名

将Formik组件上的handleSubmit替换为onSubmit,这是Formik定义提交逻辑的标准属性。

步骤2:正确传递参数给createUsuario

在onSubmit函数中,从Formik的values中取出用户输入的邮箱和密码,同时确保传入Firebase的db实例(可通过导入配置文件或上下文获取),并使用async/await处理异步操作。

修复后的注册组件代码

import React from "react";
import { View, TextInput, TouchableOpacity, Text } from "react-native";
import { Formik } from 'formik';
import * as Yup from 'yup';
import { createUsuario } from '../../CRUD';
// 导入Firebase数据库实例(根据你的实际配置路径调整)
import { db } from '../../firebaseConfig';

const SignupSchema = Yup.object().shape({
    email: Yup.string().email('El email ingresado no es valido.').required('Por favor ingrese su email.'),
    contrasenia: Yup.string()
      .min(6, 'La contrasenia es muy corta.')
      .max(20, 'La contrasenia es demasiado larga.')
      .required('Por favor ingrese su contrasenia.')
});

export default function RegisterForm () {
    return(
        <Formik 
            initialValues={{ email: '', contrasenia: '' }}
            validationSchema={SignupSchema}
            // 修正为onSubmit属性,并正确传递参数
            onSubmit={async (values) => {
                try {
                    await createUsuario(db, values.email, values.contrasenia);
                    console.log('注册成功');
                    // 这里可以添加注册成功后的跳转或提示逻辑
                } catch (error) {
                    console.error('注册失败:', error);
                    // 处理错误提示
                }
            }}
        >
            {({ values, errors, touched, handleChange, setFieldTouched, isValid, handleSubmit }) => (
                <View>
                    <TextInput 
                        placeholder="Email" 
                        value={values.email} 
                        onChangeText={handleChange('email')}
                        onBlur={() => setFieldTouched('email')}
                    />
                    {touched.email && errors.email && (
                        <Text>{errors.email}</Text>
                    )}
                    <TextInput 
                        placeholder="Contraseña" 
                        value={values.contrasenia} 
                        onChangeText={handleChange('contrasenia')}
                        onBlur={() => setFieldTouched('contrasenia')}
                        secureTextEntry={true}
                    />      
                    {touched.contrasenia && errors.contrasenia && (
                        <Text>{errors.contrasenia}</Text>
                    )}
                    <TouchableOpacity 
                        disabled={!isValid} 
                        style={{ backgroundColor: isValid ? '#289D8C' : '#808080' }} 
                        onPress={handleSubmit}
                    >
                        <Text>Registrate</Text>
                    </TouchableOpacity>
                </View>
            )}
        </Formik>
    )
}

补充优化建议

  • 原createUsuario函数中同时使用了await和.then/.catch,可以统一为try/catch风格,代码更简洁:
export async function createUsuario(db, email, contrasenia) {
    try {
        await setDoc(doc(db, "Usuario"), { email, contrasenia });
        console.log("Guardado exitosamente");
    } catch (error) {
        console.log("Hubo fallos al guardar:", error);
        throw error; // 抛出错误让上层组件处理
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 17:10:24