原来:
class Login extends React.Component{
//初始化状态
state = {
username:'',
password:''
}
saveUsername = (event)=>{
//没有传参时,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>
)
}
}
<input onChange={this.saveUsername}:把saveUsername这个函数交onchange作为回调,DOM有变化时就会调用
优化一:使用高阶函数与函数柯里化
saveFormData = (dataType)=>{
return (event)=>{
this.setState({[dataType]:event.target.value})
}
}
//把saveFormData的返回值(是个函数)交给onchange作为回调,所以当DOM有变化时,会不断调用这个返回值函数
用户名:<input onChange={this.saveFormData('username')} type="text" name="username"/>
高阶函数:
符合下面2个规范中的任何一个的函数:
- 若A函数,接收的参数是一个函数,那么A就可以称之为高阶函数。如Promise、setTimeout、数组身上一些常见的方法(比如arr.map()
- 若A函数,调用的返回值依然是一个函数,那么A就可以称之为高阶函数
函数的柯里化:
通过函数调用继续返回函数的方式,实现多次接收参数后统一处理的函数编码形式
/* function sum(a,b,c){
return a+b+c
} */
function sum(a){
return(b)=>{
return (c)=>{
return a+b+c
}
}
}
const result = sum(1)(2)(3)
注意:
不把saveFormData写成
saveFormData = (dataType)=>{
this.setState({[dataType]:event.target.value})
//不能写成 this.setState({dataType:event.target.value}) 会在state里新增一个名为dataType的key:
/*因为
let a = 'name'
let obj = {}
obj[a] = 'tom'
console.log(obj); // {name:'tom'}
*/
}
的原因:
<input onChange={this.saveFormData('username')}:是把saveFormData的返回值作为onchange的回调,这样为undefined。但是必须把函数给onchange作为回调
优化二(推荐)
saveFormData = (dataType,event)=>{
this.setState({[dataType]:event.target.value})
}
用户名:<input onChange={event => this.saveFormData('username',event) } type="text" name="username"/>