🎭 React表单组件的"双面人生":受控与非受控的巅峰对决

79 阅读3分钟

🤔 引子:表单组件的两种性格

想象你正在经营一家餐厅,有两位性格迥异的服务员:

  • 小控 :凡事一丝不苟,每笔订单都要向你汇报,你说一他不敢说二
  • 小放 :随心所欲,自己记订单,只有结账时才告诉你结果 在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>
  )
}

🎯 受控组件的三大特征

  1. 数据双向绑定 :输入框的值 value 与React状态 value 绑定
  2. 实时响应 :用户输入时立即触发 onChange 更新状态
  3. 即时反馈 :像密码长度验证这样的功能可以实时进行

🎭 生活中的受控组件

想象你在玩游戏时的"实时存档"功能——每走一步都自动保存,永远不用担心进度丢失!受控组件就是这样,用户的每一个输入都会被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>
  )
}

🎯 非受控组件的三大特征

  1. DOM自主管理 :输入框的值由DOM自身管理
  2. 引用访问 :通过 ref 直接访问DOM元素获取值
  3. 按需获取 :只有在需要时(如提交表单)才读取值

🎭 生活中的非受控组件

这就像你点外卖——平时不管外卖小哥在哪里,只有在他送到门口时你才会和他交互。非受控组件也是如此,平时它自己玩自己的,只有在需要数据时我们才通过ref去找它。

⚔️ 巅峰对决:受控VS非受控

Snipaste_2025-07-19_21-07-09.png

🧠 智慧选择:何时用哪种组件?

  • 受控组件:表单的检测等需要实时反馈的场景
  • 非受控组件:性能好、交互不强的简单场景

🌟 小技巧

  • 当你需要实时验证、格式化输入或动态禁用提交按钮时,选受控组件
  • 当你只需要在提交时获取一次值,或者处理文件上传时,选非受控组件
  • 复杂表单优先考虑受控组件,简单场景可以用非受控组件偷懒😄

🎬 实战剧场:两种组件的同台演出

在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代码。