🤔 引子:表单组件的两种性格
想象你正在经营一家餐厅,有两位性格迥异的服务员:
- 小控 :凡事一丝不苟,每笔订单都要向你汇报,你说一他不敢说二
- 小放 :随心所欲,自己记订单,只有结账时才告诉你结果 在React世界里,表单组件也有这样两种性格——受控组件(Controlled Components)和非受控组件(Uncontrolled Components)。今天我们就通过 一个项目,揭开它们的神秘面纱!
🕵️♂️ 受控组件:严格自律的"好学生"
先认识一下我们的第一位主角——受控组件。它就像那种上课认真听讲、笔记工整的好学生,一切行动听指挥。
🔍 代码探秘
在App.jsx 中,我们找到了它的庐山真面目:
function ControledInput({onSubmit}) {
const [value, setValue] = useState('') // 响应式状态
const [error, setError] = useState('')
const handleSubmit = (e) => {
e.preventDefault()
console.log(value,'/////');
onSubmit(value)
}
const handleChange = (e) => {
setValue(e.target.value)
// 频繁触发 实时判断表单是否合格
if (e.target.value.length < 6) {
setError('密码不能小于6位')
} else {
setError('')
}
}
return (
<form onSubmit={handleSubmit}>
<label htmlFor="controled-input">受控组件</label>
<input
type="text"
value={value} {/* 受state控制 */}
onChange={handleChange} {/* 实时更新state */}
required
/>
{error && <p style={{color: 'red'}}>⚠️ {error}</p>} {/* 实时错误提示 */}
<input type='submit' value="提交"/>
</form>
)
}
🎯 受控组件的三大特征
- 数据双向绑定 :输入框的值 value 与React状态 value 绑定
- 实时响应 :用户输入时立即触发 onChange 更新状态
- 即时反馈 :像密码长度验证这样的功能可以实时进行
🎭 生活中的受控组件
想象你在玩游戏时的"实时存档"功能——每走一步都自动保存,永远不用担心进度丢失!受控组件就是这样,用户的每一个输入都会被React记录在案。
🤸♀️ 非受控组件:自由奔放的"艺术家"
现在让我们欢迎第二位主角——非受控组件。它就像那些即兴表演的艺术家,不按套路出牌,但总能给你惊喜!
🔍 代码探秘
同样在 App.jsx 中,我们找到了非受控组件的实现:
function UncontroledInput({onSubmit}) {
const inputRef = useRef(null) // 创建引用对象
const handleSubmit = (e) => {
e.preventDefault()
const value = inputRef.current.value // 直接从DOM获取值
console.log(value, '23333333333333')
onSubmit(value)
}
return (
<form onSubmit={handleSubmit}>
<label htmlFor="uncontroled-input">非受控组件</label>
<input
type="text"
id='uncontroled-input'
ref={inputRef} {/* 将引用附加到DOM元素 */}
/>
<input type='submit' value="提交"/>
</form>
)
}
🎯 非受控组件的三大特征
- DOM自主管理 :输入框的值由DOM自身管理
- 引用访问 :通过 ref 直接访问DOM元素获取值
- 按需获取 :只有在需要时(如提交表单)才读取值
🎭 生活中的非受控组件
这就像你点外卖——平时不管外卖小哥在哪里,只有在他送到门口时你才会和他交互。非受控组件也是如此,平时它自己玩自己的,只有在需要数据时我们才通过ref去找它。
⚔️ 巅峰对决:受控VS非受控
🧠 智慧选择:何时用哪种组件?
- 受控组件:表单的检测等需要实时反馈的场景
- 非受控组件:性能好、交互不强的简单场景
🌟 小技巧
- 当你需要实时验证、格式化输入或动态禁用提交按钮时,选受控组件
- 当你只需要在提交时获取一次值,或者处理文件上传时,选非受控组件
- 复杂表单优先考虑受控组件,简单场景可以用非受控组件偷懒😄
🎬 实战剧场:两种组件的同台演出
在App组件中,我们同时渲染了这两种组件:
function App() {
const handleSubmit = (value) => {
console.log(value, '???????')
}
return (
<div style={{display: 'flex', gap: '20px', justifyContent: 'center', marginTop: '50px'}}>
<ControledInput onSubmit={handleSubmit}/>
<UncontroledInput onSubmit={handleSubmit}/>
</div>
)
}
想象一下这个画面:左边的受控组件实时检查你的输入,右边的非受控组件默默等待提交——它们就像React世界里的"严父慈母",用不同方式守护着你的表单数据!
🎭 总结:没有最好,只有最合适
受控组件和非受控组件没有绝对的好坏,就像筷子和勺子各有用武之地。掌握它们的特性,根据实际场景灵活选择,才能写出优雅的React代码。