(注:這篇博客參考自redux-form的官方英文文檔)左轉http://redux-form.com/6.5.0/examples/syncValidation/html
在這篇博客裏,我將用redux-form實現一個同步驗證的表單,它將知足如下條件:react
1有三個輸入框:用戶名輸入框(username),郵箱輸入框(email)和年齡輸入框(age)redux
2若是點擊輸入框獲取焦點後未輸入內容,則在輸入框失去焦點後發出錯誤(error)提示:XXX不能爲空,且此時不能提交成功api
3若是在輸入框中輸入內容不合法,好比用戶名過長(length>5)發出錯誤提示:不能大於五個字,且此時不能提交成功數組
4若是在輸入框中輸入內容合法但需警告,則提示警告(warn)內容,此時雖然發出警告但仍能提交成功(請區分和2和3中的區別)less
5在還沒有輸入內容時(pristine=true)或在提交過程當中(submitting=true),禁止使用提交按鈕。在點擊清空按鈕時,調用reset()方法清空全部輸入框中的內容函數
首先附上form.js的代碼:(這份展現一共兩份代碼:index.js和form.js,index.js的內容請看上一篇博客)spa
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組件?code
Field組件是redux-form組件庫中的核心組件,它位於你的輸入框(input)或輸入框組件的外一層,將其包裝起來從而使輸入框能和redux的store直接鏈接起來。component
它有兩個最重要的屬性:name屬性和component屬性,且這兩個屬性都是必填項
<Field name="username" type="text" component={renderField} label="Username"/>
在上面的Field中name和component是必填的,而type屬性和label屬性是選填的,但選填的屬性(如type和label)可經過props屬性傳入它的component中,好比以上的renderField中
2Field組件的name屬性和component屬性
{ username:彭湖灣, email:2314838003@qq.com, age:20 }
1純字符串如input
, textarea
或者 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/
運行結果以下:
1--驗證是否爲空
2--驗證是否知足格式
3
4