溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

redux-form V.7.4.2學(xué)習(xí)筆記(六)表單同步校驗技術(shù)

發(fā)布時間:2020-07-28 00:02:38 來源:網(wǎng)絡(luò) 閱讀:1275 作者:googlingman 欄目:web開發(fā)

一、客戶端同步校驗支持

redux-form V.7.4.2提供了兩種方法可以為表單提供同步客戶端校驗支持。

第一種是為整個redux-form提供校驗函數(shù),該函數(shù)接受一個以表單中所有值組成的對象作為參數(shù)并返回一個帶有所有錯誤信息的對象。具體實現(xiàn)方式也分為兩種形式:(1)通過將校驗函數(shù)作為配置參數(shù)提供給經(jīng)過裝飾的表單組件來完成的;(2)作為props提供給經(jīng)過裝飾的表單組件來完成的。這也是本文要討論的校驗方案。

第二種是為每個字段使用單獨的校驗器。后面文章中我們也會討論字段級表單驗證的示例。

此外,還可以為redux-form提供具有與校驗函數(shù)相同類型簽名的警告函數(shù)。警告方式并不是將表單標(biāo)記為無效的,這在某種意義上允許兩種層次嚴(yán)重錯誤的發(fā)生(這個結(jié)論只有通過深入分析有關(guān)源碼才能徹底弄明白,由于時間原因我也沒有分析這部分源碼,所以在此先略去進一步討論)。

另外需要提示的是,這里提供的示例校驗函數(shù)純粹是為了簡化演示目的。在實際的應(yīng)用程序中,建議構(gòu)建某種類型的可重用校驗系統(tǒng)。

【注意】通常使用可重用的無狀態(tài)函數(shù)組件來渲染每個字段。重要的是,這不是使用內(nèi)聯(lián)方式定義的(在render函數(shù)中),因為在每次渲染時以及觸發(fā)每一個字段的重新渲染時都要進行校驗——因為此時組件prop將發(fā)生變化。

幾個重要結(jié)論

(1)如果校驗函數(shù)返回錯誤,并且表單當(dāng)前由于發(fā)生各種錯誤而沒有渲染字段,則表單將被視為有效的并會被提交。

(2)表單數(shù)據(jù)每次更改時都會進行同步校驗;因此,如果你的字段值無效,則將始終存在一個field.error值。一旦你的字段被修改了,你可能只想顯示校驗錯誤——這種情況下當(dāng)你的字段上發(fā)生onBlur事件時redux-form會為設(shè)置一個專門的標(biāo)記。最終,當(dāng)提交表單時,所有字段都標(biāo)記為已觸摸(也就是已修改,一些特殊情況下,例如系統(tǒng)已經(jīng)內(nèi)置提供了某種數(shù)據(jù),如果你點擊一下對應(yīng)字段,說明「已觸摸」,這種情況也算是「已修改」的特殊情形),從而允許顯示任何校驗錯誤。

(3)在你的校驗函數(shù)中,值可能未定義,因此在驗證嵌套字段時請?zhí)貏e注意。如果沒有注意這個問題,那么你可能會遇到一些“TypeError:undefined”這樣的錯誤提示。

本文將簡要討論redux-form支持下的同步表單校驗支持,包括了錯誤和警告型配置。官方Demo中只演示了輸入框的校驗,而這里準(zhǔn)備了包括 radio selecttextarea 的校驗方式。~~

官方示例分析

官方示例的核心文件是redux-form-synchronous-validation.js,其中文件與絕大部分的其他實例保持一致,在此不作贅述。

運行時快照

redux-form V.7.4.2學(xué)習(xí)筆記(六)表單同步校驗技術(shù)

注意到,上圖中在尚未點按提交按鈕的情況下,無論是輸入了不合格式要求的郵箱數(shù)據(jù),還是輸入不在指定范圍內(nèi)的年齡數(shù)據(jù),校驗子系統(tǒng)都給出相應(yīng)的錯誤提示信息。從源碼跟蹤分析來看,redux-form這個庫的核心是一個不到900行代碼的名為createReduxForm.js的文件。上圖中錯誤信息都是由React.js系統(tǒng)完成的。也就是說,redux-form只提供校驗、錯誤、警告等數(shù)據(jù)部分(包括判斷函數(shù))的抓取分析,最終的可能的錯誤提示是交由React系統(tǒng)(通過createElement方法)完成的。

代碼分析

在此,我們只關(guān)注與表單整體校驗有關(guān)的部分。下面還是先來看一下實例代碼(SyncValidationForm.js,僅直接相關(guān)部分):

const validate = values => {
  const errors = {}
  if (!values.username) {
    errors.username = 'Required'
  } else if (values.username.length > 15) {
    errors.username = 'Must be 15 characters or less'
  }
  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'
  }
  if (!values.age) {
    errors.age = 'Required'
  } else if (isNaN(Number(values.age))) {
    errors.age = 'Must be a number'
  } else if (Number(values.age) < 18) {
    errors.age = 'Sorry, you must be at least 18 years old'
  }
  return errors
}

const warn = values => {
  const warnings = {}
  if (values.age < 19) {
    warnings.age = 'Hmm, you seem a bit young...'
  }
  return warnings
}

const SyncValidationForm = (props) => {
  //......
}

export default reduxForm({
  form: 'syncValidation',  // a unique identifier for this form
  validate,                // <--- validation function given to redux-form
  warn                     // <--- warning function given to redux-form
})(SyncValidationForm)

其實,上面代碼中主要有兩句話:
(1)reduxForm函數(shù)中出現(xiàn)了validate和warn兩個參數(shù)(ES6對象屬性的簡潔表示方式),這兩個鍵值定義如上;
(2)上面定義了兩個相應(yīng)于(1)中命名的函數(shù),分別實現(xiàn)規(guī)則范圍內(nèi)數(shù)據(jù)的判定與可能的錯誤及警告信息的確定。

再補充一點的話,reduxForm函數(shù)中出現(xiàn)的validate和warn兩個參數(shù),在官方API中已有明確功能說明,各自的英文說明如下(因為比較規(guī)則,在此不作翻譯):
(1)關(guān)于validate函數(shù)
//validate : (values:Object, props:Object) => errors:Object [optional]
//a synchronous validation function that takes the form values and props passed
// into your component. If validation passes, it should return {}.
// If validation fails, it should return the validation errors in the form { field1: <String>, field2: <String> }.
// Defaults to (values, props) => ({}).

(2)關(guān)于warn函數(shù)
//warn : (values:Object, props:Object) => warnings:Object [optional]
//a synchronous warning function that takes the form values and props passed into your component.
// Warnings work the same as validations, but do not mark a form as invalid.
// If the warning check passes, it should return {}. If the check fails, it should return the
// warnings in the form { field1: <String>, field2: <String> }. Defaults to (values, props) => ({}).

可見,這兩個函數(shù)都返回一個簡單包含相應(yīng)信息的對象。當(dāng)然,在一切順利的情況下,其返回的對象應(yīng)該是{}。至于這些信息的最終渲染是交由React系統(tǒng)實現(xiàn)的。

補充

參考資料(1)中tedyuen提供的基于官方示例的修改版本值得有興趣的朋友進一步試驗學(xué)習(xí),畢竟官方示例只是提供了一種指導(dǎo)思想,實際的開發(fā)卻要求你必須去面對各種復(fù)雜的表單組件的校驗問題。

參考

(1)https://github.com/tedyuen/react-redux-form-v6-example#snycValidation
(2)https://redux-form.com/7.4.2/examples/syncvalidation/

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI