redux-form的學習筆記二--實現表單的同步驗證


:這篇博客參考自redux-form的官方英文文檔)左轉http://redux-form.com/6.5.0/examples/syncValidation/

在這篇博客里,我將用redux-form實現一個同步驗證的表單,它將滿足以下條件:

1有三個輸入框:用戶名輸入框(username),郵箱輸入框(email)和年齡輸入框(age)

2如果點擊輸入框獲取焦點后未輸入內容,則在輸入框失去焦點后發出錯誤(error)提示:XXX不能為空,且此時不能提交成功

3如果在輸入框中輸入內容不合法,比如用戶名過長(length>5)發出錯誤提示:不能大於五個字,且此時不能提交成功

4如果在輸入框中輸入內容合法但需警告,則提示警告(warn)內容,此時雖然發出警告但仍能提交成功(請區分和2和3中的區別)

5在尚未輸入內容時(pristine=true)或在提交過程中(submitting=true),禁止使用提交按鈕。在點擊清空按鈕時,調用reset()方法清空所有輸入框中的內容

首先附上form.js的代碼:(這份展示一共兩份代碼:index.js和form.js,index.js的內容請看上一篇博客)

import React from 'react'
import { Field, reduxForm } from 'redux-form'

const validate = values => {
  const errors = {}
  if (!values.username) {
    errors.username = '用戶名不能為空'
  } else if (values.username.length > 5) {
    errors.username = '不能大於五個字'
  }
  if (!values.email) {
    errors.email = '郵箱不能為空'
  } else if (!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(values.email)) {
    errors.email = 'Invalid email address'
  }
  if (!values.age) {
    errors.age = '年齡不能為空'
  } else if (isNaN(Number(values.age))) {
    errors.age = '年齡必須是一個數字'
  } else if (Number(values.age) < 18) {
    errors.age = '對不起,你未滿18歲'
  }
  return errors
}

const warn = values => {
  const warnings = {}
  if (values.age < 19) {
    warnings.age = '你年齡還有點小哦!'
  }
  return warnings
}

const renderField = ({ input, label, type, meta: { touched, error, warning } }) => (
  <div>
    <label>{label}</label>
    <div>
      <input {...input} placeholder={label} type={type}/>
      {touched && ((error && <span>{error}</span>) || (warning && <span>{warning}</span>))}
    </div>
  </div>
)

const SyncValidationForm = (props) => {
  const { handleSubmit, pristine, reset, submitting } = props
  return (
    <form onSubmit={handleSubmit}>
      <Field name="username" type="text" component={renderField} label="Username"/>
      <Field name="email" type="email" component={renderField} label="Email"/>
      <Field name="age" type="number" component={renderField} label="Age"/>
      <div>
        <button type="submit" disabled={submitting}>Submit</button>
        <button type="button" disabled={pristine || submitting} onClick={reset}>Clear Values</button>
      </div>
    </form>
  )
}
export default reduxForm({
  form: 'syncValidation',  //你的redux-form的特殊標記,必填項
  validate,                // 上面定義的一個驗證函數,使redux-form同步驗證
  warn                     // 上面定義的一個錯誤提示函數,使redux-form同步錯誤提示
})(SyncValidationForm)//寫入的redux-form組件
 

1什么是Field組件?

Field組件是redux-form組件庫中的核心組件,它位於你的輸入框(input)或輸入框組件的外一層,將其包裝起來從而使輸入框能和redux的store直接連接起來。

它有兩個最重要的屬性:name屬性和component屬性,且這兩個屬性都是必填項   

<Field name="username" type="text" component={renderField} label="Username"/>

在上面的Field中name和component是必填的,而type屬性和label屬性是選填的,但選填的屬性(如type和label)可通過props屬性傳入它的component中,比如以上的renderField中

2Field組件的name屬性和component屬性

  • name屬性是Filed組件的名稱,也即Field下輸入框的名稱,它將成為存儲form表單數據的values對象中的屬性名:比如👆的SyncValidationForm的values對象在輸入后是這樣的:
{
username:彭湖灣,
email:2314838003@qq.com,
age:20
}
  • component屬性的值是Field包裹的input組件,它可有三種形式:

1純字符串如inputtextarea 或者 select:

<Field name="username" component="input" />

2組件名稱:通過class定義的組件或者無狀態函數組件(stateless function)

<1>class定義

class MyInput extends Component {
  render() {
   .......
  }
}
<Field name="myField" component={MyInput}/>

<2>無狀態函數組件:

const  Myinput = (props) => {
  return (<input ... />)
}
<Field name="myField" component={MyInput}/>

注意!:只要寫函數名即可,不要寫html的格式,要寫成component={Myinput}而不是component={<Myinput />}!

3reduxForm(...)(yourForm)有何作用?

熟悉redux數據流的同學應該對這個函數很熟悉吧,沒錯,它和redux的connect(...)(...)函數非常類似,通過

reduxForm({
  form: 'syncValidation',  //你的redux-form的特殊標記,必填項
  validate,                // 一個驗證函數,使redux-form同步驗證
  warn                     // 一個錯誤提示函數,使redux-form同步錯誤提示
})(SyncValidationForm)//寫入的redux-form組件

(這里的validate和warn采用了ES6的對象屬性的簡化寫入寫法,相當於validate:validate和warn:warn)

一方面實現了對使redux-form實現了同步驗證等功能,同時還將handleSubmit等自帶的屬性以props的形式傳入SyncValidationForm中,使他“增強”了,是不是和connect(...)(...)很相似呢?然后通過

const SyncValidationForm = (props) => {
  const { handleSubmit, pristine, reset, submitting } = props
    .....       
}

你就在SyncValidationForm中取到了這些屬性值

關於handleSubmit,pristine,reset和submitting的作用我這里簡單介紹一下,詳細的大家可以去看英文的API:左轉http://redux-form.com/6.5.0/docs/api/Props.md/

  • handleSubmit是處理提交的一個函數,接收三個參數:values(即上文提到的保存表單數據的對象),dispatch和props(傳遞給自定義表單組件的屬性)
  • pristine是一個布爾型的值,如果表單初始化后尚未輸入值,為true,否則為false,當你向表單中第一個輸入框中輸入值的時候,pristine就由true轉為false了
  • reset是一個函數,調用reset()可清空表單
  • submitting是一個布爾型數值,true表示表單正在提交

 運行結果如下:

1--驗證是否為空

2--驗證是否滿足格式

3

4


免責聲明!

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



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