formik來實現表單校驗


表單驗證說明

  • 表單提交前,需要先進性表單驗證,驗證通過后再提交表單
  • 方式一:antd-mobile 組件庫的方式(需要InputItem文本輸入組件)
  • 推薦:使用更通用的 formik,React中專門用來進行表單處理和表單校驗的庫

介紹

  • Github地址:formik文檔
  • 場景:表單處理,表單驗證
  • 優勢:輕松處理React中的復雜表單,包括:獲取表單元素的值,表單驗證和錯誤信息,處理表單提交,並且將這些內容放在一起統一處理,有利於代碼閱讀,重構,測試等
  • 使用兩種方式:1. 高階組件(withFormik) 2. render-props(<Formik render={() => {}} />)

formik來實現表單校驗(★★★)

重構

  • 安裝: yarn add formik
  • 導入 withFormik,使用withFormit 高階組件包裹Login組件
  • 為withFormit提供配置對象: mapPropsToValues / handleSubmit
  • 在Login組件中,通過props獲取到values(表單元素值對象),handleSubmit,handleChange
  • 使用values提供的值,設置為表單元素的value,使用handleChange設置為表單元素的onChange
  • 使用handleSubmit設置為表單的onSubmit
  • 在handleSubmit中,通過values獲取到表單元素值
  • 在handleSubmit中,完成登錄邏輯

// Login組件中
render() {
  // const { username, password } = this.state

  // 通過 props 獲取高階組件傳遞進來的屬性
  const { values, handleSubmit, handleChange } = this.props

  return (
    <div className={styles.root}>
      {/* 頂部導航 */}
      <NavHeader className={styles.navHeader}>賬號登錄</NavHeader>
      <WhiteSpace size="xl" />

      {/* 登錄表單 */}
      <WingBlank>
        <form onSubmit={handleSubmit}>
          <div className={styles.formItem}>
            <input
              className={styles.input}
              value={values.username}
              onChange={handleChange}
              name="username"
              placeholder="請輸入賬號"
            />
          </div>
          {/* 長度為5到8位,只能出現數字、字母、下划線 */}
          {/* <div className={styles.error}>賬號為必填項</div> */}
          <div className={styles.formItem}>
            <input
              className={styles.input}
              value={values.password}
              onChange={handleChange}
              name="password"
              type="password"
              placeholder="請輸入密碼"
            />
          </div>
          {/* 長度為5到12位,只能出現數字、字母、下划線 */}
          {/* <div className={styles.error}>賬號為必填項</div> */}
          <div className={styles.formSubmit}>
            <button className={styles.submit} type="submit">
              登 錄
            </button>
          </div>
        </form>
        <Flex className={styles.backHome}>
          <Flex.Item>
            <Link to="/registe">還沒有賬號,去注冊~</Link>
          </Flex.Item>
        </Flex>
      </WingBlank>
    </div>
  )
}

// 使用 withFormik 高階組件包裝 Login 組件,為 Login 組件提供屬性和方法
Login = withFormik({
  // 提供狀態:
  mapPropsToValues: () => ({ username: '', password: '' }),
  // 表單的提交事件
  handleSubmit: async (values, { props }) => {
    // 獲取賬號和密碼
    const { username, password } = values

    // 發送請求
    const res = await API.post('/user/login', {
      username,
      password
    })

    console.log('登錄結果:', res)
    const { status, body, description } = res.data

    if (status === 200) {
      // 登錄成功
      localStorage.setItem('hkzf_token', body.token)

      // 注意:無法在該方法中,通過 this 來獲取到路由信息
      // 所以,需要通過 第二個對象參數中獲取到 props 來使用 props
      props.history.go(-1)
    } else {
      // 登錄失敗
      Toast.info(description, 2, null, false)
    }
  }
})(Login)

兩種表單驗證方式

  • 兩種方式

    • 通過validate 配置手動校驗

  • 通過 validationSchema 配置項配合Yup來校驗

  • 推薦: validationSchema配合Yup的方式進行表單校驗

給登錄功能添加表單驗證

  • 安裝: yarn add yup (Yup 文檔),導入Yup
// 導入Yup
import * as Yup from 'yup'
  • 在 withFormik 中添加配置項 validationSchema,使用 Yup 添加表單校驗規則

  • 在 Login 組件中,通過 props 獲取到 errors(錯誤信息)和 touched(是否訪問過,注意:需要給表單元素添加 handleBlur 處理失焦點事件才生效!)
  • 在表單元素中通過這兩個對象展示表單校驗錯誤信

示例代碼:

// 使用 withFormik 高階組件包裝 Login 組件,為 Login 組件提供屬性和方法
Login = withFormik({
  ...
  // 添加表單校驗規則
  validationSchema: Yup.object().shape({
    username: Yup.string()
      .required('賬號為必填項')
      .matches(REG_UNAME, '長度為5到8位,只能出現數字、字母、下划線'),
    password: Yup.string()
      .required('密碼為必填項')
      .matches(REG_PWD, '長度為5到12位,只能出現數字、字母、下划線')
  }),
  ...
})(Login)

在結構中需要渲染錯誤信息:

{/* 登錄表單 */}
<WingBlank>
  <form onSubmit={handleSubmit}>
    ...  用戶名的錯誤提示
    {errors.username && touched.username && (
      <div className={styles.error}>{errors.username}</div>
    )}
    ... 密碼框的錯誤提示
    {errors.password && touched.password && (
      <div className={styles.error}>{errors.password}</div>
    )}
    ...
</WingBlank>

簡單處理

  • 導入 Form組件,替換form元素,去掉onSubmit

  • 導入Field組件,替換input表單元素,去掉onChange,onBlur,value

  • 導入 ErrorMessage 組件,替換原來的錯誤消息邏輯代碼

  • 去掉所有 props

示例代碼:

// 導入withFormik
import { withFormik, Form, Field, ErrorMessage } from 'formik'

<Form>
  {/* 賬號 */}
  <div className={styles.formItem}>
    <Field
      className={styles.input}
      name="username"
      placeholder="請輸入賬號"
    />
  </div>
  <ErrorMessage
    className={styles.error}
    name="username"
    component="div"
  />
  {/* 密碼 */}
  <div className={styles.formItem}>
    <Field
      className={styles.input}
      name="password"
      type="password"
      placeholder="請輸入密碼"
    />
  </div>
  <ErrorMessage
    className={styles.error}
    name="password"
    component="div"
  />
  <div className={styles.formSubmit}>
    <button className={styles.submit} type="submit">
      登 錄
    </button>
  </div>
</Form>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM