日期:2024年11月21日

处理表单

表单是网页中必不可少的组件,本节课我们来看看在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去操作表单,并不建议使用,所以这里便不再赘述了。

5 2 投票数
文章评分
订阅评论
提醒
guest

5 评论
最旧
最新 最多投票
内联反馈
查看所有评论
Chin
2 年 前

打卡

captrue
captrue
2 年 前

密码框绑定的数据写成邮箱的啦

xiaoguabushigua
xiaoguabushigua
2 年 前

当表单里面的元素很多时,每个都要写一个 ChangeHandler 事件吗?这也太麻烦了吧!

aiw
aiw
1 年 前

不是每次更新state时都会重新渲染组件嘛,那么每输入一个字符state都会修改,然后重新渲染组件,那不是不好嘛,所以我看别人说用非受控组件好

5
0
希望看到您的想法,请您发表评论x