Github 地址: github.com/reeli/react…javascript
看這篇文章以前,你須要掌握的知識:html
form 能夠說是 web 開發中的最大的難題之一。跟普通的組件相比,form 具備如下幾個特色:java
異步
獲取數據的,那麼連續兩次用戶輸入拿到的數據也有可能存在 "後發先至" 的問題。正由於以上這些特色,使 form 的開發變得困難重重。在接下來的章節中,咱們會將 RxJS 和 Form 結合起來,幫助咱們更好的去解決這些問題。react
在實現咱們本身的 Form 組件以前,讓咱們先來參考一下原生的 HTML Form。git
對於一個 Form 組件來講,須要保存全部表單元素的信息(如 value, validity 等),HTML Form 也不例外。 那麼,HTML Form 將表單狀態保存在什麼地方?如何才能獲取表單元素信息?github
主要有如下幾種方法:web
<form>
表單節點。document.forms[0].elements[0].value; // 獲取第一個 form 中第一個表單元素的值
const form = document.querySelector("form");
form.elements[0].value;
form.addEventListener('submit', function(event) {
console.log(event.target.elements[0].value);
});
複製代碼
表單校驗的類型通常分爲兩種:typescript
novalidate
屬性能夠關閉瀏覽器的自動校驗。<form novalidate>
<input name='username' required/>
<input name='password' type='password' required minlength="6" maxlength="6"/>
<input name='email' type='email'/>
<input type='submit' value='submit'/>
</form>
複製代碼
var $form = document.querySelector('form');
function getFormValues(form) {
var values = {};
var elements = form.elements; // elemtns is an array-like object
for (var i = 0; i < elements.length; i++) {
var input = elements[i];
if (input.name) {
switch (input.type.toLowerCase()) {
case 'checkbox':
if (input.checked) {
values[input.name] = input.checked;
}
break;
case 'select-multiple':
values[input.name] = values[input.name] || [];
for (var j = 0; j < input.length; j++) {
if (input[j].selected) {
values[input.name].push(input[j].value);
}
}
break;
default:
values[input.name] = input.value;
break;
}
}
}
return values;
}
$form.addEventListener('submit', function(event) {
event.preventDefault();
getFormValues(event.target);
console.log(event.target.elements);
console.log(getFormValues(event.target));
});
複製代碼
感興趣的同窗能夠先去看一下源碼 github.com/reeli/react…瀏覽器
RxJS 是一個很是強大的數據管理工具,但它並不具有用戶界面渲染的功能,而 React 卻特別擅長處理界面。那何不將它們的長處結合起來?用 React 和 RxJS 來解決咱們的 Form 難題。既然知道了它們各自的長處,因此分工也就比較明確了:網絡
RxJS 負責管理狀態,React 負責渲染界面。
與 Redux Form 不一樣的是,咱們不會將 form 的狀態存儲在 store 中,而是直接保存在 <Form/>
組件中。而後利用 RxJS 將數據通知給每個 <Field/>
,而後 <Field/>
組件會根據數據去決定本身是否須要更新 UI,須要更新則調用 setState
,不然什麼也不作。
舉個例子,假設在一個 Form 中有三個 Field (以下),當只有 FieldA 的 value 發生變化時, 爲了避免讓