持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第13天,点击查看活动详情
前言
上篇文章说明了一下受控组件和非受控组件,React文档指出尽量少用Refs,所以说要多用受控组件,受控组件中表单每个输入标签都有自己独立的函数,这样非常繁琐,接下来想办法使用一个函数处理不同的输入标签的内容。
直接上代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>学习React</title>
</head>
<body>
<div id="test"></div>
<script type="text/javascript" src="./js/react.development.js"></script>
<script type="text/javascript" src="./js/react-dom.development.js"></script>
<script type="text/javascript" src="./js/babel.min.js"></script>
<script type="text/babel">
class Login extends React.Component {
state = {
username: '',//用户名
password: '' //密码
}
saveFormData = (dataType) => {
return (event) => {
this.setState({ [dataType]: event.target.value })
}
}
handleSubmit = (event) => {
event.preventDefault() //阻止表单提交
const { username, password } = this.state
alert(`你输入的用户名:${username},你输入的密码是:${password}`)
}
render() {
return (
<form onSubmit={this.handleSubmit}>
用户名:<input onChange={this.saveFormData('username')} type="text" name='username' />
密码:<input onChange={this.saveFormData('password')} type="password" name='password' />
<button>登录</button>
</form>
)
}
}
ReactDOM.render(<Login />, document.getElementById('test'))
</script>
</body>
</html>
在saveFormData这个方法中的event是React维护的一个事件对象,DataType是通过函数传递的,event不能通过函数传递 接收
saveFormData函数返回了一个函数,在这个返回函数中接受 了事件对象event,saveFormData 接受的内容是对象的键,是一个字符串,想要访问其变化的值,还是需要和event.target.value,接下来 setState第一个参数要读取一个变量,而不是一个字符串。初始化的state是一个object对象,不是数组。所以使用[dataType]获取变量的值
举一个例子更好地理解这个[dataType]:
高阶函数
上面的例子中saveFormData就是高阶函数,那么什么是高阶函数
定义: 高阶函数:如果一个函数符合下面其中一个,那么这个函数就是高阶函数。
- 若某个函数接收的参数是一个函数,那么该函数就可以称之为高阶函数
- 若某个函数调用的返回值依然是一个函数,那么该函数就可以称之为高阶函数
常见高阶函数有:Promise(内置的构造函数) ,setTimeout(),arr.map()等等
函数的柯里化:通过函数的调用继续返回函数的方式,实现多次接收参数最后统一处理的函数编码方式 简单例子展示理解:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>学习React</title>
</head>
<body>
<script type="text/javascript">
function sum(a, b, c) {
return a + b + c
}
function mysum(a) {
return (b) => {
return (c) => {
return a + b + c
}
}
}
console.log(sum(1, 2, 3))
console.log(mysum(1)(2)(3))
</script>
</body>
</html>
效果:
如果不使用高阶函数也可以让saveFormData接收到value和dataType,就可以在调用saveFormData的时候传递两个参数,一个是值一个是要设置的state键值:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>学习React</title>
</head>
<body>
<div id="test"></div>
<script type="text/javascript" src="./js/react.development.js"></script>
<script type="text/javascript" src="./js/react-dom.development.js"></script>
<script type="text/javascript" src="./js/babel.min.js"></script>
<script type="text/babel">
class Login extends React.Component {
state = {
username: '',//用户名
password: '' //密码
}
saveFormData = (dataType, event) => {
this.setState({ [dataType]: event.target.value })
}
handleSubmit = (event) => {
event.preventDefault() //阻止表单提交
const { username, password } = this.state
alert(`你输入的用户名:${username},你输入的密码是:${password}`)
}
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>
)
}
}
ReactDOM.render(<Login />, document.getElementById('test'))
</script>
</body>
</html>
补充知识箭头函数简写
箭头函数左侧只有一个参数的话括号()可以省略,右侧只有一句话花括号省略
用户名:<input onChange={(event) => { this.saveFormData('username', event) }} type="text" name='username' />
密码:<input onChange={(event) => { this.saveFormData('password', event) }} type="password" name='password' />
上面两句代码可以简写成:
用户名:<input onChange={event => this.saveFormData('username', event) } type="text" name='username' />
密码:<input onChange={event => this.saveFormData('password', event) } type="password" name='password' />