这篇笔记记录了React中收集表单数据的一些知识
一、本堂课重点内容
- 收集表单数据的知识点
二、详细知识点介绍
1、非受控组件定义
- 受控与非受控是从组件的角度出发来说出的概念,字面意思就是组件是不被控制的,不被谁控制,当然是不被父组件控制,那么不受控制的组件的特性就是一切逻辑只与自身有关,与其他的组件没有通信与交集
- 在HTML当中,像
input
、checkbox
等这类表单元素会维持自身状态,并根据用户输入进行更新。但在React中,这些组件在不加以处理的情况下都是非受控组件,因为真正使用的时候会发现这些组件是不会自动更新值的,我们输入的值在不做任何处理的情况是无法拿到使用输入的值的 - 非受控的组件的组件状态并不受外部环境控制,而是封闭在组件内部
- 非受控组件的数据是现用现取的,需要用到的时候再去调用
- e.g.
class Login extends React.Component{
handleSubmit = (event)=>{
event.preventDefault() //阻止表单提交
const {username,password} = this
alert(`你输入的用户名是:${username.value},你输入的密码是:${password.value}`) // 现用现取
}
render(){
return(
<form onSubmit={this.handleSubmit}>
用户名:<input ref={c => this.username = c} type="text" name="username"/>
密码:<input ref={c => this.password = c} type="password" name="password"/>
<button>登录</button>
</form>
)
}
}
2、受控组件定义
- 不使用 ref,会把值存放在state状态中,用的时候直接去状态中取。类似于vue(v-model)和angualr中的双向数据绑定
- 归纳受控组件的逻辑
- 可以通过初始state中设置表单的默认值;
- 每当表单的值发生变化时,调用onChange事件处理器;
- 事件处理器通过事件对象e拿到改变后的输入值,并更新应用的state
- setUserName触发视图的重新渲染,完成表单组件值得更新
- e.g.
class Login extends React.Component{
//初始化状态
state = {
username:'', //用户名
password:'' //密码
}
//保存用户名到状态中
saveUsername = (event)=>{
this.setState({username:event.target.value})
}
//保存密码到状态中
savePassword = (event)=>{
this.setState({password:event.target.value})
}
//表单提交的回调
handleSubmit = (event)=>{
event.preventDefault() //阻止表单提交
const {username,password} = this.state
alert(`你输入的用户名是:${username},你输入的密码是:${password}`)
}
render(){
return(
<form onSubmit={this.handleSubmit}>
用户名:<input onChange={this.saveUsername} type="text" name="username"/>
密码:<input onChange={this.savePassword} type="password" name="password"/>
<button>登录</button>
</form>
)
}
}
3、函数柯里化
- 在上一部分中写的登录组件里,为了接收用户名和密码写了两个函数,我们可以将其合并为一个
saveFormData
函数,接收username
或password
作为参数来判断输入的是用户名还是密码 - 但是这样的话,以用户名为例,input就要写成这样:
<input onChange={this.saveUsername('username')} type="text" name="username"/>
saveUsername
会先执行一次返回一个undefined
给onChange
,导致无法监听事件- 这时,可以采用柯里化的方法,设置
saveFormData
的返回值为一个函数 - js小知识点:
const a = 'b' b = {a: '1'} // 得到 {a: 1} c = {[a]: '2'} // 得到 {b: 2}
- 高阶函数:如果一个函数符合下面2个规范中的任何一个,那该函数就是高阶函数。
- 若A函数,接收的参数是一个函数,那么A就可以称之为高阶函数。
- 若A函数,调用的返回值依然是一个函数,那么A就可以称之为高阶函数。
- 常见的高阶函数有:
Promise
、setTimeout
、arr.map()
等等
- 函数的柯里化:通过函数调用继续返回函数的方式,实现多次接收参数最后统一处理的函数编码形式。
4、不用柯里化的写法
class Login extends React.Component{
//初始化状态
state = {...}
//保存表单数据到状态中
saveFormData = (dataType,event)=>{
this.setState({[dataType]:event.target.value})
}
//表单提交的回调
handleSubmit = ...
render(){
return(
<form onSubmit={this.handleSubmit}>
用户名:<input onChange={event => this.saveFormData('username',event) } type="text" name="username"/>
密码:<input onChange={event => this.saveFormData('password',event) } type="password" name="password"/>
<button>登录</button>
</form>
)
}
}
三、实践练习例子
- 已在上一节中列出
四、课后个人总结
- 受控组件有一点像Vue中的双向数据绑定v-model