在本教程中,我們將看看如何使用React和HTML5的現代組合來處理表單提交和驗證。
當我們在Web應用程序中討論用戶輸入時,我們經常首先想到HTML表單。Web表單從HTML的第一個版本開始就已經可用。顯然,該功能已於1991年推出,並在1995年以RFC 1866標準進行了標準化。我們在任何地方都使用它們,幾乎每個庫和框架。但是React呢?Facebook就如何處理表單提供了有限的意見。主要是為交互事件訂閱表單和控件,並通過“value”屬性傳遞狀態。因此表單驗證和提交邏輯取決於您。體面的用戶界面意味著你可以覆蓋“on submit”/“on input”字段驗證,內聯錯誤消息,根據有效性切換元素,“原始”,“提交”狀態等邏輯。我們能不能抽象出這種邏輯並簡單地將它插入我們的表格中?我們當然可以。唯一的問題是採取什麼方法和解決方案。
DevKit中的表單
如果你喜歡去的devkit ReactBootstrap或AntDesign你很可能已經高興的形式。兩者都提供組件來構建滿足不同要求的表單。例如,在AntDesign中,我們使用元素和帶有的表單字段來定義表單,該 是集合中任何輸入控件的封裝。您可以在上設置驗證規則,如:
這是一個簡單的形式,除了一件事 - 輸入元素有一個 required 屬性。所以如果我們立即按下提交按鈕,表單將不會被髮送到服務器。相反,我們會在輸入旁邊看到一個工具提示,說明該值不符合給定的約束(即該字段不應為空)。
現在我們將輸入設置為一個附加約束:
所以這個值不僅僅是必需的,而且必須遵從給定的正則表達式pattern。
錯誤信息雖然不是那種信息,是嗎?我們可以對其進行定製(例如,解釋我們對用戶的期望)或者只是翻譯:
const answer = document.querySelector( "[name=answer]" );
answer.addEventListener( "input", ( event ) => {
if ( answer.validity.patternMismatch ) {
answer.setCustomValidity("Oh, it's not a right answer!");
} else {
answer.setCustomValidity( "" );
}
});
所以基本上,在輸入事件中,它檢查patternMismatch 輸入有效性狀態的 屬性狀態。任何時候實際值與模式不匹配,我們定義錯誤消息。如果我們 對控件有任何其他限制,我們也可以在事件處理程序中覆蓋它們。
對工具提示不滿意?是的,他們在不同的瀏覽器中看起來不一樣。我們添加下面的代碼:
const answer = document.querySelector( "[name=answer]" ),
answerError = document.querySelector( "[name=answer] + [data-bind=message]" );
answer.addEventListener( "input", ( event ) => {
answerError.innerHTML = answer.validationMessage;
});
即使只是這個超級簡短的介紹,你可以看到技術的力量和靈活性。本機表單驗證非常好。那麼,為什麼我們要依靠無數的定製庫?為什麼不使用內置驗證?
React符合表單驗證API
react-html5-form將React(以及可選的Redux)連接到HTML5 Form Validation API。它公開組件Form 和 InputGroup (類似於Formsy的自定義輸入或 FormItem 在AntDesign中)。因此, Form 定義了表單及其範圍,並 定義了可以包含一個或多個輸入的字段的範圍。我們只是用這些組件包裝任意形式的內容(只是簡單的HTML或React組件)。在用戶事件中,我們可以請求表單驗證,並獲得更新後的狀態 和組件,因此,對底層輸入有效性。 InputGroupFormInputGroup
那麼,讓我們在實踐中看到它。首先,我們定義表單範圍:
import React from "react";
import { render } from "react-dom";
import { Form, InputGroup } from "Form";
const MyForm = props => (
);
render( <myform>, document.getElementById( "app" ) );
該作用域接收具有屬性的狀態對象:
- 錯誤 - 表單錯誤消息(通常是服務器驗證消息)。我們可以設置它 form.setError()。
- valid - 布爾值,指示所有基礎輸入是否符合指定約束。
- pristine - 布爾值,指示用戶是否尚未與表單交互。
- submitting - 表示正在處理表單的布爾值(按下提交按鈕時切換為true,並在用戶定義的異步onSubmit 處理程序解析後立即返回false )。
- form - 用於訪問API的Form組件的實例。
這裡我們使用just pristine 和submitting properties來將提交按鈕切換到禁用狀態。
為了在提供表單內容時註冊輸入進行驗證,我們將它們包裝在一起 InputGroup
{({ error, valid }) => (
<label>Email address/<label>
type="email"
required
name="email"
id="emailInput" />
{ error && (
)}
通過validate 道具,我們指定了團隊的哪些輸入應該被註冊。[ "email" ] 意味著我們有唯一的輸入,名稱為“電子郵件”。
在範圍中,我們收到具有以下屬性的狀態對象:
- 錯誤 - 所有已註冊輸入的錯誤消息數組。
- 錯誤 - 最後發出的錯誤消息。
- valid - 布爾值,指示所有基礎輸入是否符合指定約束。
- inputGroup - 訪問API的組件實例。
渲染之後,我們得到一個帶有電子郵件字段的表單。如果該值為空或在提交時包含無效的電子郵件地址,則會在輸入旁邊顯示相應的驗證消息。
請記住,我們在使用本機Form Validation API時正在努力處理自定義錯誤消息?在以下情況下更容易 InputGroup:
onInput( e, inputGroup, form ) } id="emailInput" />
從現在開始,只要我們改變輸入值就會被驗證,如果它無效,我們會立即收到錯誤信息。
你可以從上面的例子中找到演示的源代碼。
順便說一句,你喜歡將組件派生的表單狀態樹連接到Redux存儲嗎?我們也可以做到這一點。
該軟件包公開了html5form 包含所有註冊表單的狀態樹的reducer 。我們可以像這樣將它連接到商店:
import React from "react";
import { render } from "react-dom";
import { createStore, combineReducers } from "redux";
import { Provider } from "react-redux";
import { App } from "./Containers/App.jsx";
import { html5form } from "react-html5-form";
const appReducer = combineReducers({
html5form
});
// Store creation
const store = createStore( appReducer );
render( <provider>
, document.getElementById( "app" ) );
現在,當我們運行應用程序時,我們可以在商店中找到所有與表單相關的狀態。
這是一個專用演示的源代碼。
概括
React沒有內置的表單驗證邏輯。但我們可以使用第三方解決方案。所以它可以是一個DevKit,它可以是一個表單生成器,它可以是一個HOC或包裝器組件,將表單驗證邏輯混合到任意形式的內容中。我個人的方法是一個包裝組件,它依賴於HTML內置的表單驗證API並在表單和表單域的範圍內公開有效性狀態。
閱讀更多 愛碼農 的文章