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 发生变化时, 为了避免让