javascript - 将错误数据从 Firebase 或服务器响应传递给 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 }) => {
  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()
        }}
      />
    </>
  )
}

我已经对其进行了测试,(几乎)一切正常。

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

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

这就是我很难弄清楚该怎么做的原因。我是否需要创建上下文来传递值?是否有更简单和/或更直接的方式来分享这些值(value)观?

最佳答案

因为你想依赖来自服务器的错误,你必须将它设置在 Formik 中的 onSubmit使用 setErrorssetFieldError方法并设置特定字段名的错误消息。

像下面这样的东西可能会达到这个结果:

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()
        }}
      />
    </>
  )
}

并且在您的 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>
  )
}

或者您可以使用 <ErrorMessage name="myErrorFieldName"/>显示消息的组件:https://jaredpalmer.com/formik/docs/api/errormessage#docsNav

关于javascript - 将错误数据从 Firebase 或服务器响应传递给 Formik,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58003057/

相关文章:

firebase - 如何向 firebase.auth() 添加附加信息

php - 为什么我的JS函数在动态添加内容到页面后不起作用?

javascript - 当我尝试通过 Id 获取标签时,为什么我的 jQuery 不工作?

javascript - 如何使用angularjs为控件赋值

javascript - + 使用 javascript 传递值时缺少符号

javascript - 当所有屏幕通过 React Navigation 获得焦点时,在每个屏幕上执行相同的功能

javascript - 尝试运行 Mocha 测试时 require.context 不是函数

angular - 如何理解复杂的 TypeScript 泛型类型?

java - 任务成功后附加参数未存储在 Firebase 数据库中?

ios - 如何将 Firebase 进度计数单位转换为百分比