受控
一、受控组件
1.1 认识
每当表单的状态发生变化时,都会被写入到组件的 state
中,这种组件在 React
中被称为受控组件(controlled component
) 简而言之,受状态控制的表单组件为受控组件
1.2 流程
React
受控组件更新 state
的流程
-
可以通过在初始
state
中设置表单的默认值。 -
每当表单的值发生变化时,调用
onChange
事件处理器。 -
事件处理器通过合成事件对象
e
拿到改变后的状态,并更新应用的state
。 -
setState
触发视图的重新渲染,完成表单组件值的更新。
1.3 语法
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
value: '',
};
}
handleChange(e) {
const {value} = e.target;
this.setState(
{
value,
},
() => {
console.log(this.state.value);
},
);
}
render() {
return (
<div>
<input
type="text"
value={this.state.value}
onChange={(e) => {
this.handleChange(e);
}}
/>
</div>
);
}
}
二、非受控组件
2.1 认识
如果一个表单组件没有 value props
(单选按钮和复选框对应的是 checked prop
)时,就可以称为非受控组件。简而言之,不受状态控制的表单组件为非受控组件
2.2 流程
在 React
中,非受控组件是一种反模式,它的值不受组件自身的 state
或 props
控制。通常,需要通过为其添加 ref prop
来访问渲染后的底层 DOM
元素
2.3 语法
class App extends React.Component {
constructor(props) {
super(props);
}
handleChange(e) {
const {value} = this.refs.value;
this.setState({value}, () => {
console.log(this.state.value);
});
}
render() {
return (
<div>
<input
type="text"
ref="value"
onChange={(e) => {
this.handleChange(e);
}}
/>
</div>
);
}
}
三、问题
3.1 说说对受控组件和非受控组件的理解, 以及应用场景?
受控组件中: 表单元素(如 <input>
、<textarea>
、<select>
)的状态由 React
的 state
明确控制, 表单元素的值完全受 React state
驱动。用户交互触发 onChange
事件 → 更新 state
→ 组件重渲染 → UI
显示更新后的 state
。适用于: 1. 实时表单验证(如登录、注册、表单校验); 2. 实时输入格式化、动态展示(如金额输入、电话号码格式化); 3. 与 React
状态紧密绑定的交互场景(例如搜索实时联想)
import { useState } from 'react';
function ControlledInput() {
const [value, setValue] = useState('');
const handleChange = (e) => {
setValue(e.target.value); // 状态实时同步到 state
};
return (
<input type="text" value={value} onChange={handleChange} />
);
}
非受控组件: 直接使用 DOM
自己维护状态, React
只在需要时通过 ref
获取输入的值, 表单元素值由 DOM
管理, React
不会实时干涉。使用时通过 ref
或表单事件获取元素的值(如表单提交时)。适用于: 1. 一次性表单提交(如大量表单字段一次性提交,无需中途实时控制); 2. 表单较为复杂,追求性能,不需要实时交互反馈的场景; 3. 与第三方库、DOM
集成(如上传文件、富文本编辑器)
import { useRef } from 'react';
function UncontrolledInput() {
const inputRef = useRef(null);
const handleSubmit = (e) => {
e.preventDefault();
alert(inputRef.current.value); // 通过 ref 获取值
};
return (
<form onSubmit={handleSubmit}>
<input type="text" ref={inputRef} />
<button type="submit">提交</button>
</form>
);
}