React教程第24部分:第二形式课

今天,我们继续讨论在React中使用表单的问题。 上一次,我们检查了组件和文本字段交互的功能。 在这里,我们讨论使用其他表单元素。

图片

第1部分:课程概述,React,ReactDOM和JSX普及的原因
第2部分:功能组件
第3部分:组件文件,项目结构
第4部分:父级和子级组件
第5部分:TODO应用程序的开始工作,样式设计的基础
第6部分:关于本课程的一些功能,JSX和JavaScript
第7部分:内联样式
第8部分:继续研究TODO应用程序,熟悉组件的属性
第9部分:组件属性
第10部分:使用组件特性和样式的研讨会
第11部分:动态标记生成和映射数组方法
第12部分:研讨会,TODO应用程序的第三阶段工作
第13部分:基于类的组件
第14部分:关于基于类的组件,组件状态的研讨会
第15部分:组件健康研讨会
第16部分:TODO应用程序的第四阶段工作,事件处理
第17部分:TODO应用程序的第五阶段工作,修改组件的状态
第18部分:TODO应用程序的第六阶段工作
第19部分:组件生命周期方法
第20部分:条件渲染的第一课
第21部分:关于条件渲染的第二课​​和研讨会
第22部分:TODO应用程序的第七阶段工作,从外部资源下载数据
第23部分:关于使用表格的第一课
第24部分:第二形式课
第25部分:使用表单的研讨会
第26部分:应用程序体系结构,容器/组件模式
第27部分:课程项目

课42.处理表单,第2部分


原创

在本课程中,我们将讨论用于输入多行文本的字段,标志,单选按钮(也称为“单选按钮”)和列表字段。 迄今为止,我们仅考虑使用普通文本输入字段。
这是App组件的代码,我们将从今天的实验开始:

 import React, {Component} from "react" class App extends Component {   constructor() {       super()       this.state = {           firstName: "",           lastName: ""       }       this.handleChange = this.handleChange.bind(this)   }     handleChange(event) {       const {name, value} = event.target       this.setState({           [name]: value       })   }     render() {       return (           <form>               <input                   type="text"                   value={this.state.firstName}                   name="firstName"                   placeholder="First Name"                   onChange={this.handleChange}               />               <br />               <input                   type="text"                   value={this.state.lastName}                   name="lastName"                   placeholder="Last Name"                   onChange={this.handleChange}               />                             {                   /**                    *    :                    *                    * <textarea />                    * <input type="checkbox" />                    * <input type="radio" />                    * <select>  <option>                    */               }                             <h1>{this.state.firstName} {this.state.lastName}</h1>           </form>       )   } } export default App 

这是工作阶段的应用程序页面在浏览器中的外观。


浏览器中的应用程序页面

表单通常不仅包含在其中输入短行的字段。 当为表单配备其他元素时,在React中使用它们会有点复杂,尽管这没有什么特别的。

在上面的代码中,有一个注释掉的片段,列出了我们将要讨论的元素。 让我们从输入多行文本的字段开始textarea元素。 了解如何与他合作可能是最容易的。 如果您在构建常规HTML表单时曾经使用此元素,那么您将知道它不是自闭标签,与input元素一样。 它具有打开和关闭部分。
通过在注释后立即插入以下代码,将此元素添加到表单中:

 <br /> <textarea></textarea> 

如果现在查看应用程序页面,则可以看到用于输入多行文本的字段如何显示在该页面上。


在页面上输入文本的字段

如您所见,此字段比普通字段稍高,用户可以使用其右下方的标记来更改其大小。 多亏了rowscols您可以在描述此元素时指定其尺寸。 在普通HTML中,如果要在显示字段后在其中添加一些文本,可以通过在元素的开始和结束标记之间输入所需的文本来完成。 在React中,使用这种元素的方式与使用input元素的方式尽可能相似,这是我们上次谈到的。 也就是说,在React中, textarea标签是自动关闭的。 即,可以如下更改用于在页面上显示字段的代码:

 <textarea /> 

此外,您可以在此标记中使用value属性,其处理方式与普通文本字段的相同属性完全相同。 因此,在处理不同元素时实现了一致性,此外,通过更新与此类字段关联的状态属性,更容易更新字段的内容。 让我们将域代码的状态转换为以下形式:

 <textarea value={"Some default value"}/> 

当指定的文本显示在页面上时,这将导致指定的文本显示在字段中。


显示在字段中的文本

我们将继续使用该字段来输入多行文本,但现在我们将讨论标志。 复选框是input控件,其类型为checkbox 。 这是他的描述:

 <input type="checkbox" /> 

这是此标记描述的标志在页面上的样子。


复选框

此控件的主要特征是在使用它时不使用value属性。 它用于为用户提供一些两个选项的选择,其中一个对应于复选框,另一个对应于未选中的选项。 为了跟踪该复选框是选中还是未选中,使用了checked属性,该属性由逻辑值描述。 结果,标志通常对应于状态中存储的逻辑属性。

让我们将组件的状态转换为以下形式:

 this.state = {   firstName: "",   lastName: "",   isFriendly: true } 

标志描述代码更改如下:

 <input   type="checkbox"   checked={this.state.isFriendly} /> 

之后,选定的复选框将显示在页面上。


选中框

是的,现在他将不响应对他的点击。 事实是该标志绑定到状态中存储的相应变量,因此,在本例中,当我们尝试将其删除时,React会检查状态并发现isFriendly属性设置为true不允许这样做。 同时,控制台中将显示一条警告,指出我们未提供用于更改字段的机制( onChange事件onChange ),并且该字段以只读状态显示。


控制台警告

我们可能会编写一个特殊的方法来处理该标志,但是我们组件的代码已经具有handleChange()方法。 现在,它用于处理文本字段。 我们将考虑如何使用它与旗帜一起使用。 为此,首先将上述方法分配为该标志的onChange事件onChange并为该标志分配一个名称,该名称对应于与该标志相关的state属性的名称。 另外,我们将使用label标记对标志进行签名:

 <label>    <input       type="checkbox"       name="isFriendly"       checked={this.state.isFriendly}       onChange={this.handleChange}   /> Is friendly? </label> 

handleChange()方法中,其代码如下所示,在处理文本字段时,我们找到了元素的名称( name )及其内容( value ),之后我们通过向状态写入带有特定名称的字段来更新状态。其value属性:

 handleChange(event) {   const {name, value} = event.target   this.setState({       [name]: value   }) } 

现在,我们需要弄清楚如何处理没有value属性的标志。 它仅具有checked属性,该属性只能接受truefalse值。 结果,为了使用handleChange()方法来处理标志,我们需要检查为其调用此处理程序的元素是否为标志。 为了执行此检查,我们记得代表该标志的input元素的类型( type )设置为checkbox 。 要检查此值,可以引用event.target元素的type属性。 我们将使用以下结构从event.target以及checked属性中提取此属性:

 const {name, value, type, checked} = event.target 

现在,我们可以检查type常量的值,并找出为其调用事件处理程序的元素是否为标志。 如果是这种情况,我们将把原来被checked常量写入状态。 不要忘记保存负责处理文本字段的代码。 结果, handleChange()代码采用以下形式:

 handleChange(event) {   const {name, value, type, checked} = event.target   type === "checkbox" ? this.setState({ [name]: checked }) : this.setState({ [name]: value }) } 

之后,检查标志的操作。


检查标志的操作

如您所见,现在可以将其删除并安装。 同时,文本字段的工作没有中断。 有关复选框的通知已从控制台中消失,但在那里显示了有关用于输入多行文本的字段的通知。 更改描述此字段的代码,如下所示:

 <textarea   value={"Some default value"}   onChange={this.handleChange} /> 

尽管我们没有使用组件的工具实现用于此字段的其他机制(未为该字段指定名称,也没有向该状态添加相应的属性),但这将导致通知的消失。 您可以自己实现这些功能。 现在让我们谈谈开关。

它们可以表示为textcheckbox类型的input元素的组合。 这里的意思是,这些开关同时具有value属性和checked属性。 在我们的表单中添加几个开关,基于标志描述代码创建它们的代码。 看起来是这样的:

 <label>   <input       type="radio"       name="gender"       value="male"       checked={this.state.isFriendly}       onChange={this.handleChange}   /> Male </label> <br /> <label>   <input       type="radio"       name="gender"       value="female"       checked={this.state.isFriendly}       onChange={this.handleChange}   /> Female </label> 

我们基于标志描述代码创建了此代码,但仍未进行任何编辑。 因此,开关的行为异常。 特别是,如果未选中该复选框,则两个开关都处于“关闭”状态,并且如果您选中了该复选框,则其中之一将变为“ on”。 如果根据现有元素的代码创建了元素代码,则可以通过认真对待元素代码来防止此类错误。 现在我们将修复它。
请注意,这两个元素的名称相同- gender 。 具有相同名称的交换机组成一个组。 只能选择该组中包含的一个开关。

配置开关时,如果某些状态属性为true ,则不能简单地指示将其checked值设置为true 。 交换机必须支持组内已同步的状态更改。 而是根据条件设置开关的checked值。 在我们的案例中,此条件将通过比较this.state.gender的state属性与字符串malefemale 。 在开关描述代码中,如下所示:

 <label>   <input       type="radio"       name="gender"       value="male"       checked={this.state.gender === "male"}       onChange={this.handleChange}   /> Male </label> <br /> <label>   <input       type="radio"       name="gender"       value="female"       checked={this.state.gender === "female"}       onChange={this.handleChange}   /> Female </label> 

现在,向状态添加一个新属性, gender ,用一个空字符串初始化它:

 this.state = {   firstName: "",   lastName: "",   isFriendly: false,   gender: "" } 

在那之后,无论复选框如何,开关都将起作用。 将第二级标题添加到组件的代码输出中,该标题显示有关选择哪个开关的信息:

 <h2><font color="#3AC1EF">You are a {this.state.gender}</font></h2> 

在这里,可能值得介绍一些条件渲染的机制。 当打开页面时,如果没有选择任何单选按钮,这将确保未在其上显示文本You are a ,但我们不会这样做,尽管您可以自己完全实现它。 现在,让我们看看我们得到了什么。


在应用程序页面上切换

我们在这里谈论的一切似乎都非常复杂。 特别地,这涉及不同控件的特征的记忆。 为了简化表单的工作,您可以使用专门的库。 例如, formik库。 这个库大大简化了在React应用程序中开发表单的过程。

现在让我们谈谈列表字段。

在普通的HTML中,以下构造用于描述组合框:

 <select>   <option></option>   <option></option>   <option></option> <select/> 

尽管与其他元素一样,React也采用了value属性,但是React采取了类似的方法。 这使您可以轻松准确地确定选择了哪个列表项,此外,还可以更轻松地处理组件的状态。

假设我们要创建一个组合框,允许用户选择自己喜欢的颜色。 为此,可以将以下构造放入select元素的value属性中: value={this.state.favColor} 。 这将获得用户选择的值。 现在将favColor添加到状态:

 this.state = {   firstName: "",   lastName: "",   isFriendly: false,   gender: "",   favColor: "blue" } 

接下来,我们为组合框配备onChange事件onChange并为其命名。 我们还为组合框的options元素分配值,然后输入将在框中显示的文本。

这是带有签名的select签名select元素的外观:

 <label>Favorite Color:</label> <select   value={this.state.favColor}   onChange={this.handleChange}   name="favColor" >   <option value="blue">Blue</option>   <option value="green">Green</option>   <option value="red">Red</option>   <option value="orange">Orange</option>   <option value="yellow">Yellow</option> </select> 

现在,向表单添加另一个题词,以显示用户喜欢的颜色:

 <h2><font color="#3AC1EF">Your favorite color is {this.state.favColor}</font></h2> 

现在该尝试组合框了。


组合框

正如您所看到的,尽管我们的表单并没有随着设计的复杂性而发光,但放置在其上的控件仍可以按预期工作。

借助React控件在React中的组织方式,可以轻松使用同一处理程序来处理它们的事件。 这正是我们案例中使用的工作方案。 handleChange()处理程序的唯一功能是,我们必须以特殊方式处理标志事件。

现在,让我们讨论完成表单后提交表单或处理输入到其中的值。 有两种执行此类动作的方法。 当使用其中任何一个时,表格应配备一个按钮:

 <button>Submit</button> 

在HTML5中,如果在表单中找到一个button元素,则它的作用就像是类型submit的旧input元素。 如果单击此按钮,将触发onSubmit表单本身的事件。 如果您需要在完成表单后做一些事情,可以将onClick事件onClick添加到按钮上,但是例如,我个人更喜欢通过向其分配onSubmit事件处理程序来在表单级别处理此类事件:

 <form onSubmit={this.handleSubmit}> 

尚未编写用作此事件的处理程序的方法。 这是一个常规事件处理程序,例如,它引用某个API,将表单数据传递给它。

总结


在本课程中,我们结束了有关在React中使用表单的讨论。 下次您将找到有关该主题的实际工作。

亲爱的读者们! 如果您尝试使用formik库在React中创建表单,请告诉我们。

Source: https://habr.com/ru/post/zh-CN444356/


All Articles