在 React 里,受控组件 和非受控组件是处理表单元素的两种不同方式。一个一个来看看吧。
受控组件
在 React 中,受控组件指的是表单元素(如<input>
、<textarea>
、<select>
等)的状态由 React 组件(state)掌控。表单元素的值通过value
属性设置,通过调用onChange
事件来更新其状态,从而更新页面UI。
这样的好处有:
- 表单元素的值受 React 组件状态控制。每当用户输入时,React会更新state,并将新的state值传递给表单元素,保证React在控制表单元素的值。
- 单一数据源: React组件中的state是数据的唯一来源,所有的表单元素的值都通过React的state来控制。这使得管理表单状态变得更为清晰,因为所有的数据都可以通过React的state来访问和修改。
- 只能通过onChange改变:如果没有change方法,会发现这个组件无法操作了。
举个例子:
jsx
import React, { useState } from 'react';
function ControlledInput() {
const [value, setValue] = useState('');
const handleChange = (event) => {
setValue(event.target.value);
};
const handleSubmit = (event) => {
event.preventDefault();
console.log('提交的值:', value);
};
return (
<form onSubmit={handleSubmit}>
<input
type="text"
value={value}
onChange={handleChange}
/>
<button type="submit">提交</button>
</form>
);
}
export default ControlledInput;
在上述代码中,input
元素的值由value
属性设定,并且利用onChange
事件来更新value
状态。当用户输入内容时,handleChange
函数会被调用,进而更新组件的状态。
这样就可以发现,数据的流动很清晰,维护起来更方便。
非受控组件
非受控组件指的是表单元素的状态由 DOM 本身掌控,而非 React 组件。
通常借助ref
来获取表单元素的值。
特点:
- 表单元素的值由 DOM 自身管理:在非受控组件中,输入框的值存储在DOM中,而不是在React的state中,更像是传统HTML表单。
- 通过Ref获取:在非受控组件中,开发者通常使用
React.createRef()
或useRef()
来创建引用,从而获取表单元素的当前值,而不是依赖state
来管理。
举个例子:
jsx
import React, { useRef } from 'react';
function UncontrolledInput() {
const inputRef = useRef(null);
const handleSubmit = (event) => {
event.preventDefault();
console.log('提交的值:', inputRef.current.value);
};
return (
<form onSubmit={handleSubmit}>
<input
type="text"
ref={inputRef}
/>
<button type="submit">提交</button>
</form>
);
}
export default UncontrolledInput;
在上面的这段代码中,通过useRef
创建了一个ref
对象inputRef
,然后进行对input组件进行ref标记。当提交表单时,调用ref的方法,获取input
元素的值。
使用场景
组件受控和非受控的场景其实说到底就是state 的使用。
例如在React中处理表单验证、条件渲染、动态控制、自动聚焦等场景时,受控组件是更合适的选择,能够让UI及时相应,方便地进行复杂的逻辑处理和数据操作。
如果这个表单足够简单,并且不需要过多的交互,非受控组件可以让你避免不必要的状态更新,减少复杂度,且性能更优(因为每次state的更新,组件都会重新渲染)。在一些不需要动态管理输入状态的场景中,非受控组件更加高效。
新手前端,如有不正确的地方,希望指正。