组件分类
受控组件
受控组件是React官方推荐的表单处理方式。
特点
表单数据由React组件的state完全控制,每一个表单元素的值都绑定到组件的state上,并通过onChange事件处理器来更新state。
优势
1、数据可控性:
所有输入变化都通过state管理,便于实现验证和格式化
2、实时反馈:
可即时校验输入(如密码强度检测)
3、动态交互:
支持表单字段联动(如选择国家后自动填充城市)
应用场景
- 需要实时验证的表单(如登录、注册)
- 动态表单(如多步骤向导)
- 数据需要与其他组件状态同步的场景
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>2_受控组件</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>
<script type="text/babel">
//创建组件
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>
)
}
}
//渲染组件
ReactDOM.render(<Login/>,document.getElementById('test'))
</script>
</body>
</html>
非受控组件
非受控组件允许表单数据由DOM自身管理,React通过ref直接访问DOM节点获取值。
个人理解,这种组件和传统HTML表单行为有点类似,代码量相对较少。
优势
- 代码简洁:无需定义state、事件处理逻辑
- 性能优化:减少非必要的重渲染
- 特殊场景 :文件上传(
<input type="file">)必须使用非受控模式
应用场景
- 简单表单(如《联系我们》页面)
- 性能敏感场景(如大量输入框的表格)
- 集成第三方库(如jQuery插件)
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>1_非受控组件</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>
<script type="text/babel">
//创建组件
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>
)
}
}
//渲染组件
ReactDOM.render(<Login/>,document.getElementById('test'))
</script>
</body>
</html>
区别
React受控组件和非受控组件之间的最大区别是组件的值是由React状态控制还是由DOM节点控制。
| 特性 | 受控组件 | 非受控组件 |
|---|---|---|
| 数据控制 | React state | DOM自身 |
| 更新方式 | 实时(onChange事件) | 按需(如提交时通过ref获取) |
| 代码复杂度 | 较高(需定义state和事件) | 较低(直接操作DOM) |
| 实时验证 | 支持 | 需手动实现 |
| 性能 | 频繁更新可能导致重渲染 | 减少不必要的重渲染 |
| 默认值设置 | value属性 | defaultValue或defaultChecked |