# 受控组件与非受控组件

URL: https://caijiao.org/react/chapter6/controlled-components
Source: docs/react/chapter6/controlled-components.md
Description: 在 React 中，受控组件的表单值由组件的 state 控制，数据流更加可控；而非受控组件则直接通过 DOM 引用操作，适用于简单或不需要频繁交互的场景。

## 什么是受控组件？

受控组件是指表单元素的值由 React 的 state 控制。用户输入会触发状态更新，从而重新渲染组件，保持数据一致性。

```jsx
import { useState } from 'react';

function ControlledInput() {
  const [value, setValue] = useState('');

  return (
    <input
      type="text"
      value={value}
      onChange={(e) => setValue(e.target.value)}
    />
  );
}
````

在这个例子中，`input` 的值由 `value` 状态控制，任何用户输入都通过 `onChange` 修改状态。

## 什么是非受控组件？

非受控组件使用 `ref` 直接访问 DOM 元素的值，React 不管理其状态，适用于简单、不需要频繁更新的场景。

```jsx
import { useRef } from 'react';

function UncontrolledInput() {
  const inputRef = useRef();

  const handleClick = () => {
    alert(inputRef.current.value);
  };

  return (
    <>
      <input type="text" ref={inputRef} />
      <button onClick={handleClick}>获取输入值</button>
    </>
  );
}
```

在这个例子中，输入框的值不会存储在组件状态中，而是通过 `ref` 直接读取。

## 选择哪种方式？

| 对比项    | 受控组件        | 非受控组件     |
| ------ | ----------- | --------- |
| 数据来源   | React state | DOM 本身    |
| 状态管理   | 明确、集中       | 分散、不可追踪   |
| 推荐使用场景 | 表单验证、复杂交互   | 简单表单、快速开发 |
| 可测试性   | 更易测试        | 测试复杂      |

## 总结

* **受控组件** 提供了更强的控制力和一致性，推荐用于大多数表单。
* **非受控组件** 更接近原生 HTML 表单行为，适合简单的场景。
