表单是网页中必不可少的组件,本节课我们来看看在React中如何处理表单,首先我们先来创建一个简单的表单组件:
import React from 'react';
const MyForm = () => {
return (
<form>
<div>
用户名 <input type="text"/>
</div>
<div>
密码 <input type="password"/>
</div>
<div>
电子邮件 <input type="email"/>
</div>
<div>
<button>提交</button>
</div>
</form>
);
};
export default MyForm;
首先使用React定义表单和之前传统网页中的表单有一些区别,传统网页中form需要指定action和method两个属性,而表单项也必须要指定name属性,这些属性都是提交表单所必须的。但是在React中定义表单时,这些属性通通都可以不指定,因为React中的表单所有的功能都需要通过代码来控制,包括获取表单值和提交表单,所以这些东西都可以在函数中指定并通过AJAX发送请求,无需直接在表单中设置。
首先我们来研究一下如何获取表单中的用户所填写的内容,要获取用户所填写的内容我们必须要监听表单onChange事件,在表单项发生变化时获取其中的内容,在响应函数中通过事件对象的target.value来获取用户填写的内容。事件响应函数大概是这个样子:
const nameChangeHandler= e => {
//e.target.value 表示当前用户输入的值
};
然后我们再将该函数设置为input元素的onChange事件的响应函数:
<div>
用户名 <input type="text" onChange={nameChangeHandler}/>
</div>
这样一来当用户输入内容时,nameChangeHandler就会被触发,从而通过e.target.value来获取用户输入的值。通常我们还会为表单项创建一个state用来存储值:
const [inputName, setInputName] = useState('');
const nameChangeHandler = e => {
//e.target.value 表示当前用户输入的值
setInputName(e.target.value);
};
上例中用户名存储到了变量inputName中,inputName也会设置为对应表单项的value属性值,这样一来当inputName发生变化时,表单项中的内容也会随之改变:
<div>
用户名 <input type="text" onChange={nameChangeHandler} value={inputName}/>
</div>
如此设置后,当用户输入内容后会触发onChange事件从而调用nameChangeHandler函数,在函数内部调用了setInputName设置了用户输入的用户名。换句话说用户在表单中输入内容会影响到state的值,同时当我们修改state的值时,由于表单项的value属性值指向了state,表单也会随state值一起改变。这种绑定方式我们称为双向绑定,即表单会改变state,state也可以改变表单,在开发中使用双向绑定的表单项是最佳实践。
那么表单的提交要如何处理呢?表单提交同样需要通过事件来处理,提交表单的事件通过form标签的onSubmit事件来绑定,处理表单的方式因情况而已,但是一定要注意,必须要取消默认行为,否则会触发表单的默认提交行为:
const formSubmitHandler = e => {
e.preventDefault();
/*
* username : inputName
* password : pwdInput
* email : inputEmail
* */
};
为表单绑定事件:
<form onSubmit={formSubmitHandler}>
......
</form>
如此我们便有了一个简单的表单案例,完整代码如下:
import React, {useState} from 'react'; const MyForm = () => { const [inputName, setInputName] = useState(''); const [inputPwd, setInputPwd] = useState(''); const [inputEmail, setInputEmail] = useState(''); const nameChangeHandler = e => { setInputName(e.target.value); }; const pwdChangeHandler = e => { setInputPwd(e.target.value) }; const emailChangeHandler = e => { setInputEmail(e.target.value) }; const formSubmitHandler = e => { e.preventDefault(); /* * username : inputName * password : pwdInput * email : inputEmail * */ }; return ( <form onSubmit={formSubmitHandler}> <div> 用户名 <input type="text" onChange={nameChangeHandler} value={inputName}/> </div> <div> 密码 <input type="password" onChange={pwdChangeHandler} value={inputPwd}/> </div> <div> 电子邮件 <input type="email" onChange={emailChangeHandler} value={inputEmail}/> </div> <div> <button>提交</button> </div> </form> ); }; export default MyForm;
在这个案例中,表单的所有功能包括输入、显示、提交全部都由React所处理。这种表单项在React中被称为受控组件,即表单项受React控制。当然也存在有不受控组件,但那种组件使用机会少且需要通过原生DOM去操作表单,并不建议使用,所以这里便不再赘述了。
打卡
密码框绑定的数据写成邮箱的啦
多谢提醒
当表单里面的元素很多时,每个都要写一个 ChangeHandler 事件吗?这也太麻烦了吧!
是的,所以开发时,表单项都会封装一下组件
不是每次更新state时都会重新渲染组件嘛,那么每输入一个字符state都会修改,然后重新渲染组件,那不是不好嘛,所以我看别人说用非受控组件好