React js教程:React 中的表单(10)
本文是React 教程系列的一部分。您可以在此处找到本系列之前所有帖子的链接
介绍
在上一篇文章中,我们学习了如何在 React.js 中应用样式和 CSS,以及如何自定义样式化组件。在本文中,我们将了解 Form 元素的基础知识以及 React 中受控组件的使用。这也将包括组件的生命周期。
表单基础
React 中的表单与 HTML 中的工作方式相同。它们为我们提供了用户与应用程序交互的基本媒介。开发人员的一切都依赖于表单。它为登录用户提供安全性,还提供过滤、搜索、列表等功能。“提交”上的 Form 标签重定向到另一个页面,因此最好使用 JavaScript 函数。为了实现此功能,我们采用了一种名为 Controlled Components 的技术。
React 提供了两种从表单元素获取值的方法——受控组件和非受控组件。
不受控制的组件
不受控制的组件是那些在内部存储和维护自己状态的组件。当使用不受控制的组件时,`ref` 关键字用于在需要时查找当前值。
React 不支持这种模式,但可以在只需要最终状态的开发中使用,而不必担心变量的中间状态。否则,应使用受控组件技术。
这个组件就像传统的 HTML 表单一样,因为输入表单数据存储在 DOM 内部而不是组件内部。<input> 和 <textarea> 等元素自己维护它们的状态。我们可以使用 `ref` 从 DOM 获取输入值。
例如 –
import React,{Component} from 'react';
import styled from 'styled-components';
class UserForm extends Component{
constructor(props){
super(props);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleSubmit(e){
alert('Inputted value is :'+ this.input.value);
}
render(){
return(
<form onSubmit={this.handleSubmit}>
<label>Enter Name</label>
<textarea type="text" ref={(input) => this.input = input}></textarea>
<button type="submit">Submit</button>
</form>
)
}
}
export default UserForm;
输出将显示如下。
在这里, <input> 组件存储它的状态。ref 属性用于创建对 DOM 的引用,并使其可以在需要时从那里获取值进行访问。
尽管非受控组件用于实现表单,React 更喜欢使用受控组件。Refs 提供了以 JQuery 的方式做事,而另一方面,受控组件提供了一种直接的方法,通过 React 组件处理表单数据。因此,如果您想将 Non-React 项目与 React 项目或任何快速表单开发集成,那么可以使用 `ref`。
受控组件
React 中的 Controlled 组件用于控制输入表单元素的值。呈现表单的 React 组件还根据用户输入控制表单中发生的所有事情。
受控组件有两个方面,
- 受控组件具有在每个 OnChange 事件中处理进入它们的数据的功能,而不是立即抓取数据。例如,每当用户单击提交按钮时。这个传递的数据然后被保存到状态
- 受控组件显示的数据是通过从其父/容器组件传递过来的 props 接收的。
React 遵循单向流,这意味着存在一个单向循环,从子组件输入到父组件状态,再通过 props 返回到子组件。因此,在受控组件中,我们有两种类型的容器,一种是容器组件,也称为智能组件,另一种是哑组件。
容器组件是处理数据、具有业务逻辑或进行数据调用的组件,因此它们也称为智能组件,而另一方面,哑组件只是从父容器接收数据。有时,Dubm 容器可能会像更新状态一样触发逻辑,但只能通过从父组件传递的函数来实现。
在 React 中有各种哑元件,它们只是用来接收用户输入,例如,
- <input/>
- <textarea/>
- <select/>
- <checkbox/>
- <button/>
在下面的示例中,我们将检查为 <input/> 组件制作容器组件,其他组件也类似。
让我们以一个调用 Input 组件的父组件为例,该组件也充当一个哑组件。
import React from 'react';
const Input = (props) => {
return (
<div class="form-group">
<label htmlFor={props.name} className="form-label">{props.title}</label>
<input name={props.name}
className="form-input" id={props.name}
value={props.value}
placeholder ={props.placeholder}
onChange={props.handleChange}/>
</div>
)
}
export default Input;
import React,{Component} from 'react';
import Input from './Input';
class UserForm extends Component{
constructor(props){
super(props);
this.state={
UserName:"",
handleChange : this.handleChange.bind(this)
}
this.handleSubmit = this.handleSubmit.bind(this);
}
handleSubmit(e){
alert('Inputted value is :'+ this.state.UserName);
e.preventDefault();
}
handleChange(e){
this.setState({
UserName:e.target.value
})
e.preventDefault();
}
render(){
return(
<form onSubmit={this.handleSubmit}>
<Input name={"inputText"} title={"FullName"} value={this.state.UserName}
placeholder={"Enter Name"}
handleChange={this.state.handleChange}></Input>
<button type="submit">Submit</button>
</form>
)
}
}
export default UserForm;
上述代码的输出将显示如下,
对于 <select/> 和 <checkbox/>,我们可以通过允许其多选为 true 来存储多个值,并且 value 属性将包含值数组。
我们来看一个<select/>的例子,
创建 Select.js 组件的代码如下,
import React from 'react';
const Select = (props) => {
return (
<div className="form-group">
<label htmlFor={props.name}
className="form-label">{props.title}</label>
<select onChange={props.handleChange}
name={props.name}
value={props.value}>
<option value="" >{props.placeholder}</option>
{
props.options.map(option=>{
return(
<option key={option}
value={option}
label={option}>
</option>
);
})
}
</select>
</div>
)
}
export default Select;
import React,{Component} from 'react';
import Input from './Input';
import Select from './Select';
class UserForm extends Component{
constructor(props){
super(props);
this.state={
UserName:"",
Gender:"",
genderOptions: ['Male', 'Female', 'Others']
}
this.handleInput = this.handleInput.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleSubmit(e){
alert('Inputted value is :'+ this.state.UserName + "," + this.state.Gender);
e.preventDefault();
}
handleInput(e) {
let value = e.target.value;
let name = e.target.name;
this.setState( prevState => {
return {
[name] : value
}
}, () => console.log(name + "," + value))
}
render(){
return(
<form onSubmit={this.handleSubmit}>
<Input name={"UserName"} title={"FullName"}
value={this.state.UserName}
placeholder={"Enter Name"}
handleTextInput={this.handleInput}>
</Input>
<Select name={"Gender"}
title="Gender"
value= {this.state.Gender}
options={this.state.genderOptions}
placeholder={"Select Gender"} handleChange={this.handleInput}>
</Select>
<button type="submit">Submit</button>
</form>
)
}
}
export default UserForm;
上面的代码将显示如下输出,
现在将看到,对于多个选择选项,我们需要创建一个新的事件处理程序,将值存储在数组中。
更新 UserForm.js 组件,
import React,{Component} from 'react';
import Input from './Input';
import Select from './Select';
class UserForm extends Component{
constructor(props){
super(props);
this.state={
UserName:"",
Gender:"",
Skills:[""],
genderOptions: ['Male', 'Female', 'Others'],
skillOptions: ['Programming', 'Development', 'Design', 'Testing']
}
this.handleInput = this.handleInput.bind(this);
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleSubmit(e){
alert('Inputted value is :\n Name: '+ this.state.UserName + "\n Gender: " + this.state.Gender + "\n Skills: " + this.state.Skills);
e.preventDefault();
}
handleInput(e) {
let value = e.target.value;
let name = e.target.name;
this.setState( prevState => {
return {
[name] : value
}
}, () => console.log(name + "," + value))
}
handleChange(e) {
var options = e.target.options;
var value = [];
var name = e.target.name;
for (var i = 0, l = options.length; i < l; i++) {
if (options[i].selected) {
value.push(options[i].value);
}
}
this.setState( prevState => {
return {
[name] : value
}}, () => console.log(name + "," + value))
}
render(){
return(
<form onSubmit={this.handleSubmit}>
<div class="form-group">
<Input name={"UserName"}
title={"FullName"}
value={this.state.UserName}
placeholder={"Enter Name"}
handleTextInput=this.handleInput}>
</Input>
</div>
<div class="form-group">
<Select multiple={false}
name={"Gender"}
title="Gender"
value={this.state.Gender}
options={this.state.genderOptions}
placeholder={"Select Gender"}
handleChange={this.handleInput} >
</Select>
</div>
<div class="form-group">
<Select multiple={true}
name={"Skills"}
title="Skills"
value={this.state.Skills}
options={this.state.skillOptions}
placeholder={"Select Skills"}
handleChange={this.handleChange} >
</Select>
</div>
<button type="submit">Submit</button>
</form>
)
}
}
export default UserForm;
输出将显示如下,
以同样的方式,可以使用其他元素来获取用户输入。
现在,我们将看到受控输入和非受控输入之间的区别。
不受控制的输入与受控制的输入
不受控制的输入
|
受控输入
|
不受控制的输入在内部存储自己的状态
|
受控输入将当前值存储在 props 中,并在发生任何更改时发出通知,这些更改将使用 setState 进行更新。
|
不受控制的输入可以使用 ref 关键字直接访问 DOM 元素以更新当前值
|
父组件通过处理回调和管理自己的状态来控制它,并将新值作为道具传递给受控组件。这也称为哑组件。
|
使用不受控制的输入,我们无法验证输入或格式化输入或管理动态输入
|
使用受控输入,我们可以管理输入验证、禁用提交按钮等。
|
不受控制的输入通常用于小型应用程序和不需要大量动态数据的应用程序。
|
受控输入可用于复杂应用。
|
概括
在本文中,我们了解了 React.js 中的 Forms,还了解了受控和非受控组件。在下一部分中,我们将了解 React 中的生命周期组件及其在 React 中的工作原理
本系列的下一个 >> React 中的组件生命周期
常见问题FAQ
- 程序仅供学习研究,请勿用于非法用途,不得违反国家法律,否则后果自负,一切法律责任与本站无关。
- 请仔细阅读以上条款再购买,拍下即代表同意条款并遵守约定,谢谢大家支持理解!