使用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"); }) }
错误原因分析
- Formik属性名错误:Formik组件上使用了
handleSubmit属性,但Formik要求提交逻辑必须通过onSubmit属性定义,这是触发onSubmit is not a function的直接原因。 - createUsuario参数缺失:
createUsuario需要db、email、contrasenia三个参数,但原代码调用时未传递任何参数,会导致后续数据库操作失败。 - 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
相关产品推荐
相关产品推荐

