跳到主要内容

受控

一、受控组件


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 中,非受控组件是一种反模式,它的值不受组件自身的 stateprops 控制。通常,需要通过为其添加 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>)的状态由 Reactstate 明确控制, 表单元素的值完全受 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>
);
}