根據個人粗淺經驗,若是您對Formik感興趣,而且想深刻學習與使用這個庫,我建議您仍是先對redux-form的使用邏輯與有關概念有所瞭解,並且理解和使用方面也變得容易得多的多。由於Formik中許多概念與形式與redux-form極其相似,可是各方面都簡化了不少,由於它再也不依賴於約束整個前面存儲的Redux store的限制,因爲整個前端使用一個store存儲,因此,隨着表單數量與形式變得愈來愈複雜,系統的屬性可能會受到嚴重影響——這是Formik產生的主要緣由,Formik乾脆不使用Redux,而直接操做React組件,這就有可能使得編寫表單元素雖然簡單(HTML5)但比較冗長,因而Formik也引入了相似於redux-form的一些API與props等概念(但絕對有區別)。
另外請注意,爲了與其餘流行的React文章保持一致,有些單詞沒有必要翻譯過來,例如store, values,props,shape,errors,等等。另外,touch和touched這個詞在Formik中普遍使用,意思是表單中某個字段被點擊過,此時用戶可能沒有輸入什麼數據,也有可能輸入了新的數據,都稱爲touched。所以,後面的譯文中通常翻譯爲「動過」,個別地方翻譯成「潤色」,請理解其使用情形就是。前端
<Formik>是一個幫助構建表單的組件,它也使用了相似於當前一些流行的庫(如React Motion和 React Router)的render這種prop模式。請參考下面的代碼:react
import React from 'react'; import { Formik } from 'formik'; const BasicExample = () => ( <div> <h1>My Form</h1> <Formik initialValues={{ name: 'jared' }} onSubmit={(values, actions) => { setTimeout(() => { alert(JSON.stringify(values, null, 2)); actions.setSubmitting(false); }, 1000); }} render={props => ( <form onSubmit={props.handleSubmit}> <input type="text" onChange={props.handleChange} onBlur={props.handleBlur} value={props.values.name} name="name" /> {props.errors.name && <div id="feedback">{props.errors.name}</div>} <button type="submit">Submit</button> </form> )} /> </div> );
<Formik />這個API共提供了三種渲染方法,它們是:redux
上面全部三種渲染方法都會傳遞相同的props。接下來,咱們對props每個份量做相應的解釋。app
當values與初始值不絕對相等時這個屬性的值會返回true;不然返回false(Returns true if values are not deeply equal from initial values, false otherwise)。注意:dirty屬性是隻讀的,不該該直接修改它。異步
其中包含Form校驗錯誤信息。這些信息應當與表單的定義於initialValues中的值(values)保持一致。若是你在使用validationSchema(也推薦你使用),那麼數據(原文使用的是「keys and shape」,關於shape一詞在React文章中常常見到,這裏不便直譯)應當與你的模式定義準確匹配。 從內部實現代碼來看,Formik會根據你提供的數據轉換原始的Yup校驗錯誤信息。若是你在使用validate屬性,那麼此函數會肯定錯誤對象的具體信息。ide
這是onBlur對應的事件處理器函數。當你須要跟蹤某個輸入字段是否被「動過」(touched)時頗有用。用法好比:<input onBlur={handleBlur} ... />函數
【注意】本屬性僅適用於DOM開發;若是是React Native開發則需使用setFieldTouched代替。學習
這是一個典型的輸入字段內容變化時要觸發的事件處理器。當key爲事件發出的輸入字段的name屬性時這一調用會更新values。若是name不存在,那麼handleChange函數會進一步查找輸入字段(input)的id屬性。請注意: 這裏的input意指全部HTML input標籤。ui
【注意】本屬性僅適用於DOM開發;若是是React Native開發則需使用setFieldValue代替。 翻譯
這是表單復位處理器函數,調用它將把表單還原到初始值狀態。用法好比:<button onClick={handleReset}>...</button>
這是表單提交處理器函數。 用法好比:<form onSubmit={props.handleSubmit}>...</form>。請結合本系列文章第一篇中「表單提交原理」部分加以理解。
這個屬性值表明了表單提交的當前狀態。若是表單在提交中將返回true;不然返回false。重要提醒:一旦你嘗試提交表單,Formik就會把這個值設置爲true。請結合本系列文章第一篇中「表單提交原理」部分加以理解。
在不發生錯誤的狀況下這個屬性值將爲true;或者返回當表單處於pristine條件(例如沒有dirty)時會返回isInitialValid的結果值。
若是Formik正在運行任何檢驗函數,則此屬性返回true;不然,返回false。想更多地瞭解在表單提交過程當中isValidating屬性發生了什麼變化,請結合閱讀本系列文章第一篇中「表單提交原理」部分。
強行復位表單。這個調用會清除全部錯誤及字段「潤色」信息,而且設置isSubmitting爲false,設置isValidating爲false,而且把mapPropsToValues返回值設置爲當前的WrappedComponent的props或者是傳遞過去的參數。注意:當在componentWillReceiveProps內部調用resetForm時,這是頗有用的。
強行設置errors信息。
強行設置給定字段的error信息。注意,這裏的參數field應當匹配你但願更新的errors中的key。這個屬性在編寫定製的輸入錯誤信息處理器函數時很是有用。
強行設置給定字段的touched狀態值。注意,這裏的參數field應當匹配你想更新的「動過」的key。這個屬性在編寫定製的blur處理器函數時很是有用。若是validateOnBlur的值設置爲true(默認即爲此值),那麼調用這個方法會觸發校驗運行。你也能夠經過傳遞第三個參數爲false來顯式地禁止或者跳過校驗。
觸發表單提交操做。
表明用戶嘗試提交表單的次數。當調用handleSubmit時此屬性的值會加1;可是調用handleReset後該屬性值會復位。請注意, submitCount是一個只讀屬性,不能直接修改。
強制設置一個字段的值。其中,參數field應當匹配你但願更新的values中的key。 該屬性在編寫定製的change事件處理函數時頗有用。當validateOnChange爲true (默認便是這個值)時,調用此屬性對應的函數會觸發校驗的執行。固然,你還能夠經過傳遞第三個參數爲false來顯式地禁止或者跳過校驗。
強制設置一個頂級的狀態值。這個調用用於控制你的表單的任意頂級狀態。例如,你可使用它來把API響應傳遞迴在handleSubmit調用中的你的組件內部。
強制設置isSubmitting屬性的值。
強制設置touched屬性的值。
強制設置values對象的值。
這是一個頂級的狀態對象,你可使用它來描述使用其餘方法沒法表達/存儲的表單狀態。在捕獲或者傳遞API響應給你的內部組件時這個屬性頗有用。
【注意】你僅能經過調用setStatus: (status?: any) => void來修改status。
此屬性用於潤色表單中對應的字段值。每個鍵都相應於一個剛剛被「動過」(touched)或者訪問過的字段。
這是你的表單中的values對象。其中存儲了mapPropsToValues (若是指定的話)對應的結果數據,或者存儲那些傳遞給你的被包裝組件(wrapped component)的不是函數形式的props。
【說明】包裝組件(wrapped component)一詞在諸多React/Redux文章中多見,便是指使用相似於redux-form的reduxForm API封裝後的新組件。
根據指定的方式強制你的validate屬性對應的校驗函數或者是調用validateSchema。注意,你能夠選擇性地傳遞數值進行校驗,固然這將相應地修改Formik狀態;不然,它會使用表單的當前values。
強制調用表單的validate屬性對應的函數——若是指定了相應字段的話。Formik將使用當前字段值。
下面給出此屬性的典型使用方法:
<Formik component={ContactForm} />; const ContactForm = ({ handleSubmit, handleChange, handleBlur, values, errors, }) => ( <form onSubmit={handleSubmit}> <input type="text" onChange={handleChange} onBlur={handleBlur} value={values.name} name="name" /> {errors.name && <div>{errors.name}</div>} <button type="submit">Submit</button> </form> };
【注意】<Formik component> 的優先級會高於<Formik render>;所以,你不要在同一個<Formik>中同時使用兩者。
這個屬性至關重要,請參考以下代碼瞭解其用法:
<Formik render={props => <ContactForm {...props} />} /> <Formik render={({ handleSubmit, handleChange, handleBlur, values, errors }) => ( <form onSubmit={handleSubmit}> <input type="text" onChange={handleChange} onBlur={handleBlur} value={values.name} name="name" /> {errors.name && <div> {errors.name} </div>} <button type="submit">Submit</button> </form> )} />
使用方法見下面的代碼片段:
<Formik children={props => <ContactForm {...props} />} />
//或者使用下面的方式...
<Formik> {({ handleSubmit, handleChange, handleBlur, values, errors }) => ( <form onSubmit={handleSubmit}> <input type="text" onChange={handleChange} onBlur={handleBlur} value={values.name} name="name" /> {errors.name && <div> {errors.name} </div>} <button type="submit">Submit</button> </form> )} </Formik>
默認值爲false。此屬性用於在initialValues變化時控制是否重置表單。
默認值爲false。用於控制表單加載前的isValid屬性的初始值。你也能夠傳遞一個函數。此屬性用於當你想在表單初始加載時啓用/禁用一次提交/復位按鈕操做時。
相應於表單初始字段值。Formik將使用這些值來生成例如props.values這樣的方法組件。
即便你的表單默認狀況下爲空,你也必須使用初始值來初始化全部字段;不然,React會拋出異步,說你已經把一個輸入字段從未控制(uncontrolled)狀態改變成了可控制(controlled)狀態。
【注意】 initialValues並不適用於高階組件(higher-order component);在高階組件狀況下,你須要使用mapPropsToValues代之。
對應於你可選擇使用的表單復位處理器函數。其中的參數是你的表單values,還有一個"FormikBag"值。
這是表單提交處理器函數。其中的參數是你的表單values,還有一個"FormikBag"值——其中提供了一個包含被注入的屬性(props)和方法(例如全部以set開頭——如set<Thing>的方法,還有方法resetForm)的子集的對象,以及傳遞給包裝組件的任何props。
【注意】 errors, touched,status以及全部的事件處理器函數都沒有包含在FormikBag參數中。
【注意】Formik做用特別推薦咱們使用validationSchema和Yup實現表單校驗。不管如何,表單校驗應該使用一種相對獨立的,比較直觀的方式實現——這也是每個所但願的。
另外,你可使用同步或者異步函數來實現表單校驗。請參考下面的代碼:
(1)同步校驗方式(返回一個errors對象)
// Synchronous validation const validate = (values, props) => { let errors = {}; if (!values.email) { errors.email = 'Required'; } else if (!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(values.email)) { errors.email = 'Invalid email address'; } //... return errors; };
(2)異步校驗方式(返回errors對象中的一個表明錯誤的Promise)
// Async Validation const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)); const validate = (values, props) => { return sleep(2000).then(() => { let errors = {}; if (['admin', 'null', 'god'].includes(values.username)) { errors.username = 'Nice try'; } // ... if (Object.keys(errors).length) { throw errors; } }); };
此屬性的默認值爲true。你能夠在表單blur事件觸發時使用這個屬性——更具體一些說,不管是調用handleBlur,setFieldTouched仍是setTouched均可以。
此屬性的默認值爲true。當表單觸發change事件或者相關事件時你可使用這個屬性告訴Formik進行有關校驗。 更具體一些說,不管是調用handleChange,setFieldValue仍是setValues均可以。
這個屬性很是重要,用於定義Yup模式( schema)或者是一個返回Yup模式的函數,用於校驗任務。其中,Errors會經過key映射到內部組件的errors。這個屬性的keys應當與values中的相匹配。