Javascript 将错误数据从Firebase或服务器响应传递到Formik

Javascript 将错误数据从Firebase或服务器响应传递到Formik,javascript,reactjs,firebase,react-hooks,formik,Javascript,Reactjs,Firebase,React Hooks,Formik,我有一个使用Formik创建的表单,并且已经同步到firebase。我将代码分为几个文件,其中两个文件如下: // form.js import React from 'react' import { Button } from 'UI' import { Form, Email, TextInput as Text, Password } from 'UI' export const FormFields = ({ errors, isSubmitting, isValid }) =>

我有一个使用Formik创建的表单,并且已经同步到firebase。我将代码分为几个文件,其中两个文件如下:

// form.js
import React from 'react'

import { Button } from 'UI'
import { Form, Email, TextInput as Text, Password } from 'UI'

export const FormFields = ({ errors, isSubmitting, isValid }) => {
  return (
    <Form>
      <h3>Sign Up</h3>
      <Text name="name" />
      <Email name="email" />
      <Password name="password" />
      <Password name="confirmPassword" />
      <Button disabled={!isValid || isSubmitting} type="submit">
        Submit
      </Button>
    </Form>
  )
}

// index.js
import React, { useState } from 'react'
import { Formik } from 'formik'
import * as Yup from 'yup'

import { firebase } from 'Classes'

import { FormFields as Form } from './form'
import { validationSchema } from './validation'
import { initialValues } from './values'

export const SignUpForm = () => {
  const [authError, setAuthError] = useState(null)
  console.log('authError: ', authError)

  async function authenticateUser(values) {
    const { name, email, password } = values
    try {
      await firebase.register(name, email, password)
    } catch (error) {
      console.log('Authentication error: ', error)
      setAuthError(error.message)
    }
  }

  return (
    <>
      <h1>Form</h1>
      <Formik
        render={props => {
          console.log('props: ', props)
          return <Form {...props} />
        }}
        initialValues={initialValues}
        validationSchema={validationSchema}
        onSubmit={async (
          values,
          { authError, setError, setErrors, setSubmitting, resetForm }
        ) => {
          setSubmitting(true)
          authenticateUser(values)
          setSubmitting(false)
          resetForm()
        }}
      />
    </>
  )
}
//form.js
从“React”导入React
从“UI”导入{Button}
从“UI”导入{表单、电子邮件、文本输入为文本、密码}
export const FormFields=({errors,isSubmitting,isValid})=>{
返回(
注册
提交
)
}
//index.js
从“React”导入React,{useState}
从'Formik'导入{Formik}
从“Yup”导入*为Yup
从“类”导入{firebase}
从“./Form”导入{FormFields as Form}
从“./validation”导入{validationSchema}
从“/values”导入{initialValues}
导出常量注册表=()=>{
常量[authError,setAuthError]=useState(null)
console.log('authError:',authError)
异步函数验证器(值){
const{name,email,password}=值
试一试{
等待firebase。注册(姓名、电子邮件、密码)
}捕获(错误){
console.log('身份验证错误:',错误)
setAuthError(error.message)
}
}
返回(
形式
{
console.log('props:',props)
返回
}}
initialValues={initialValues}
validationSchema={validationSchema}
onSubmit={async(
价值观
{authError、setError、setErrors、setSubmitting、resetForm}
) => {
设置提交(真)
验证器(值)
设置提交(错误)
重置表单()
}}
/>
)
}
我已经测试过了,(几乎)一切正常

我的问题与显示来自Firebase的错误消息有关。我在
index.js
文件中的
authenticateUser
函数上收到任何错误消息。这些错误存储在我用
useState
设置的
authror
变量中。它按预期工作

我想做的是将该变量或那些错误值传递到
form.js
文件,以便在需要时在表单字段中显示它们


这就是我现在很难弄明白怎么做的原因。我是否需要创建一个上下文来传递这些值?有没有一种更简单和/或更直接的方法来共享这些值?

因为您想依赖服务器的错误,所以必须使用
setErrors
setFieldError
方法在
Formik
的提交
中设置它,并设置特定字段名的错误消息

下面类似的方法可能会达到这一结果:

export const SignUpForm = () => {
  // const [authError, setAuthError] = useState(null)
  // console.log('authError: ', authError)

  async function authenticateUser(values, setFieldError) {
    const { name, email, password } = values
    try {
      await firebase.register(name, email, password)
    } catch (error) {
      console.log('Authentication error: ', error)
      // setAuthError(error.message)
      setFieldError("myErrorFieldName", error.message) // <-------------------
    }
  }

  return (
    <>
      <h1>Form</h1>
      <Formik
        render={props => {
          console.log('props: ', props)
          return <Form {...props} />
        }}
        initialValues={initialValues}
        validationSchema={validationSchema}
        onSubmit={async (
          values,
          { authError, setError, setErrors, setSubmitting, resetForm, setFieldError }
        ) => {
          setSubmitting(true)
          authenticateUser(values, setFieldError) // <-------------------
          setSubmitting(false)
          resetForm()
        }}
      />
    </>
  )
}
export const SignUpForm=()=>{
//常量[authError,setAuthError]=useState(null)
//console.log('authError:',authError)
异步函数authenticateUser(值,setFieldError){
const{name,email,password}=值
试一试{
等待firebase。注册(姓名、电子邮件、密码)
}捕获(错误){
console.log('身份验证错误:',错误)
//setAuthError(error.message)
setFieldError(“myErrorFieldName”,error.message)//{
设置提交(真)
authenticateUser(值,setFieldError)//
)
}
在form.js中,您必须根据错误对象字段存在值进行编码:

export const FormFields = ({ errors, isSubmitting, isValid }) => {
  return (
    <Form>
      <h3>Sign Up</h3>
      <Text name="name" />
      <Email name="email" />
      <Password name="password" />
      <Password name="confirmPassword" />
      <Button disabled={!isValid || isSubmitting} type="submit">
        Submit
      </Button>
      { errors.myErrorFieldName &&  <p>errors.myErrorFieldName</p> } // <----------
    </Form>
  )
}
export const FormFields=({errors,isSubmitting,isValid})=>{
返回(
注册
提交

{errors.myErrorFieldName&&errors.myErrorFieldName

}/--谢谢。就是这样。唯一的例外是
ErrorMessage
组件。它对我不起作用(即,没有显示任何内容)。但其他一切都起了作用,解决了我的问题。再次感谢。很高兴它成功了。
ErrorMessage
组件来自formik,您必须使用设置错误的确切字段名,无论哪种方式,对您有效的都应该足够好,两者都有相同的用途。