需求:
定义一个包含表单的组件
输入用户名密码后, 点击登录提示输入信息
受控组件通过event.target
获取对应的DOM节点,event.target.value
获取节点的值。 通过这种方式实现,类似于vue的双向数据绑定,input 的值 改变了,对应属性也改变;属性值 改变了, input的值也改变。建议使用受控组件,
因为非受控组件有对ref的使用,最好不要过渡使用ref。
//1、创建组件
class Demo extends React.Component {
//初始化状态
state = ({
userName: '', pwd: ''
})
saveUserName = (event) => {
// 通过event.target获取dom
this.setState({
userName: event.target.value
})
}
savePwd = (event) => {
this.setState({
pwd: event.target.value
})
}
handleSubmit = (event) => {
event.preventDefault();//阻止表单提交
const {userName, pwd} = this.state;
alert(`用户名${userName},密码${pwd}`);
}
render() {
return (
)
}
}
//2、渲染虚拟DOM
ReactDOM.render( , document.getElementById('test'))
对上述代码逐步进行优化:
方法1:高阶函数—函数珂里化
高阶函数
:如果一个函数符合下面2个规范中的任何一个,那么函数就是高阶函数:
接收的参数是一个函数
,那么A就可以称之为高阶函数调用的返回值依然是一个函数
,那么A就可以称之为高阶函数常见的高阶函数有:Promise、 setTimeout、arr.map()…
函数的珂里化
:通过函数调用继续返回调用函数的方式,实现多次接收参数最后统一处理的函数编码形式。
//1、创建组件
class Demo extends React.Component {
//初始化状态
state = ({
userName: '', pwd: ''
})
saveFormDate = (dataType) => {
//高阶函数-函数珂里化
return (event) => {
console.log(event.target.value);
this.setState({
[dataType]: event.target.value
})
}
}
handleSubmit = (event) => {
event.preventDefault();//阻止表单提交
const {userName, pwd} = this.state;
alert(`用户名${userName},密码${pwd}`);
}
render() {
return (
)
}
}
//2、渲染虚拟DOM
ReactDOM.render( , document.getElementById('test'))
方法2:不用珂里化的方法
saveFormDate = (dataType, event) => {
this.setState({
[dataType]: event.target.value
})
}
render() {
return (
)
}
方法3:使用自定义属性data-xxx=‘xxxx’
saveFormDate = (event) => {
let key=event.target.dataset.key
this.setState({
[key]: event.target.value
})
}
render() {
return (
)
}
通过ref去获取表单DOM,然后通过DOM获取表单的值,不是通过react事件去控制。
//创建组件
class Demo extends React.Component {
handleSubmit = (event) => {
event.preventDefault();//阻止表单提交
const {userName, password} = this;
alert(`用户名${userName.value},密码${password.value}`);
}
render() {
return (
)
}
}
ReactDOM.render( , document.getElementById('test'))