持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第13天,点击查看活动详情
受控组件与非受控组件
需求:定义一个包含表单的组件,在输入用户名和密码之后,点击登录提示输入信息。
受控组件
页面中,所有输入类的DOM,随着用户的输入,将值维护到状态中去,等需要用到的时候再到状态中获取,这就属于受控组件。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>受控组件</title>
</head>
<body>
<!-- 测试容器 -->
<div id="test"></div>
<!-- 加载 React 核心库 -->
<script type="text/javascript" src="../js/react.development.js"></script>
<!-- 加载 React DOM 用于支持 React 操作 DOM -->
<script type="text/javascript" src="../js/react-dom.development.js"></script>
<!-- 加载 babel 用于将 jsx 转为 js -->
<script type="text/javascript" src="../js/babel.min.js"></script>
<!-- 设置类型为babel -->
<script type="text/babel">
class LoginInfo extends React.Component {
// 初始化状态
state = {
username: '',
password: ''
}
handlerSubmit = (event) => {
// 阻止表单提交
event.preventDefault()
const {username, password} = this.state
alert('用户名:' + username + `\n` + '密码:' + password)
}
// 更新username
usernameChange = (event) => {
this.setState({username: event.target.value})
}
// 更新password
passwordChange = (event) => {
this.setState({password: event.target.value})
}
render() {
return (
<form action="http://www.baidu.com" onSubmit={this.handlerSubmit}>
用户名:<input onChange={this.usernameChange} type="text" name="username" />
密码:<input onChange={this.passwordChange} type="password" name="password" />
<button>登陆</button>
</form>
)
}
}
ReactDOM.render(<LoginInfo />, document.getElementById("test"))
</script>
</body>
</html>
非受控组件
页面中所有输入类的DOM,现用现取,都是非受控组件。
例如:登陆账号时,输入的用户名密码,在点击登陆按钮之后才去获取这两个输入框的值。
<!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>非受控组件</title>
</head>
<body>
<!-- 测试容器 -->
<div id="test"></div>
<!-- 加载 React 核心库 -->
<script type="text/javascript" src="../js/react.development.js"></script>
<!-- 加载 React DOM 用于支持 React 操作 DOM -->
<script type="text/javascript" src="../js/react-dom.development.js"></script>
<!-- 加载 babel 用于将 jsx 转为 js -->
<script type="text/javascript" src="../js/babel.min.js"></script>
<!-- 设置类型为babel -->
<script type="text/babel">
class LoginInfo extends React.Component{
render(){
return(
<form action="https://www.baidu.com" onSubmit={this.handlerSubmit}>
用户名:<input ref={c => this.username = c} type="text" name="username"/>
密码:<input ref={c => this.password = c} type="password" name="password"/>
<button>登陆</button>
</form>
)
}
handlerSubmit = (event) => {
// 阻止表单提交
event.preventDefault()
const {username, password} = this
alert('用户名:' + username.value + `\n` + '密码:' + password.value)
}
}
ReactDOM.render(<LoginInfo/>, document.getElementById("test"))
</script>
</body>
</html>
小结
受控组件相较于非受控组件,可以省略ref的定义,再React官网中有建议尽量少的去定义ref,所以,在可能的情况下,我们需要更倾向于受控组件的实现。