首先我们要明白什么时候要获取表单数据——当表单项发生变化时。
以下面的表单为例说明:
- <div className="form-item">
- <label htmlFor="date">日期label>
- <input onChange={dateChangeHandler} id="date" type="date"/>
- div>
- <div className="form-item">
- <label htmlFor="desc">内容label>
- <input onChange={descChangeHandler} id="desc" type="text"/>
- div>
- <div className="form-item">
- <label htmlFor="time">时长label>
- <input onChange={timeChangeHandler} id="time" type="number"/>
- div>
- <div className="form-btn">
- <button>添加button>
- div>
- const descChangeHandler = () => {
- console.log("DOM方式获取: ", document.getElementById('desc').value);
- };

似乎好像也没简便多少。
- const descRef = useRef();
-
- const descChangeHandler = () => {
- console.log("useRef获取: ", descRef.current.value);
- };

- // 监听内容的变化
- const descChangeHandler = (e) => {
- // 获取到当前触发事件的对象 e;e 中保存了当前事件触发时的所有信息
- // event.target 执行的是触发事件的对象(DOM对象)
- console.log(e.target.value);
- };

表单项数据填好后,需要汇总再提交至服务器。
- ......
通过监听表单onSubmit方法来提交,而通常表单不需要自行提交,由react帮你提交(异步)。
- // 创建三个变量,用来存储表单中的数据
- let inputDate = ''; // 日期
- let inputDesc = ''; // 描述
- let inputTime = 0; // 时长
然后分别在input框绑定的监听函数中通过事件对象赋值对应的输入值value。
- const formSubmitHandler = (e) => {
- // 取消表单的默认行为
- e.preventDefault();
- // 获取表单项中的数据日期、内容、时长
- // 将数据组装为一个对象
- const newLog = {
- date: new Date(inputDate),
- desc: inputDesc,
- time: +inputTime
- };
- console.log(newLog);
- };
非受控组件:说白了,就是只能通过DOM操作的表单元素。
受控组件:表单项的value受到react的state的控制管理(类似Vue中的v-model)。
我们可以将表单中的数据存储到state中,然后将state的数据设置为表单项value值。
将非受控组件元素交由state管理:
- const [inputDate, setInputDate] = useState('');
- const [inputDesc, setInputDesc] = useState('');
- const [inputTime, setInputTime] = useState('');
- "date" type="date"/>
- <input onChange={descChangeHandler} value={inputDesc} id="desc" type="text"/>
- <input onChange={timeChangeHandler} value={inputTime} id="time" type="number"/>
然后再在监听函数中调用setXXX方法获取用户输入,当表单项发生变化,state会随之变化; 反之,state发生变化,表单项也会跟着改变,这种操作称为双向绑定(个人感觉v-model真香)。
如此一来,表单就成为了一个受控组件了。
另外我们也可以将表单数据集中到一个state中:
- const [formData, setFormData] = useState({
- inputDate:'',
- inputDesc:'',
- inputTime:''
- });
监听函数的setXXX需改写成对象展开形式:
- setFormData({
- ...formData,
- inputDate: e.target.value
- });
当然还可以再精简点,这里可以只用一个函数来监听所有的input元素,给每个input设置id,通过id和保存的数据的属性名一样就可以。