React中如何实现受控组件与非受控组件
作者:前端大白话
啥是 React 里的受控组件和非受控组件
在 React 开发里,组件可分为受控组件和非受控组件,它们处理表单数据的方式各有不同。接下来咱就用通俗易懂的大白话详细说说它们的实现原理、方法、区别、作用和应用场景。
受控组件
受控组件就像是一个被人紧紧牵着线的风筝,它的数据完全由 React 组件来控制。也就是说,表单元素的值是由 React 组件的状态来决定的,表单元素的任何变化都会触发 React 组件的状态更新。
以下是一个简单的受控组件示例:
import React, { useState } from 'react';
// 定义一个名为 ControlledInput 的函数组件
function ControlledInput() {
// 使用 useState 钩子创建一个名为 value 的状态变量,初始值为空字符串
const [value, setValue] = useState('');
// 定义一个名为 handleChange 的函数,用于处理输入框的值变化事件
const handleChange = (event) => {
// 通过 event.target.value 获取输入框的最新值,并使用 setValue 更新状态
setValue(event.target.value);
};
// 渲染一个输入框,将 value 状态绑定到输入框的 value 属性上
// 当输入框的值发生变化时,调用 handleChange 函数更新状态
return (
<div>
<input
type="text"
value={value}
onChange={handleChange}
/>
<p>你输入的内容是: {value}</p>
</div>
);
}
export default ControlledInput;
实现原理
受控组件的实现原理基于 React 的单向数据流。表单元素的值由 React 组件的状态来控制,当表单元素的值发生变化时,会触发一个事件处理函数,在这个函数里更新组件的状态,从而更新表单元素的值。
方法
用 useState 钩子或者类组件的 this.state 来创建一个状态变量,用于存放表单元素的值。
把状态变量绑定到表单元素的 value 属性上。
给表单元素添加一个 onChange 事件处理函数,在函数里更新状态变量。
作用和应用场景
受控组件适合需要实时验证用户输入、根据用户输入动态更新 UI 或者与其他组件共享表单数据的场景。比如登录表单、搜索框等。
非受控组件
非受控组件就像是一只自由飞翔的鸟,它的数据由 DOM 自己来管理。也就是说,表单元素的值是由 DOM 来维护的,React 组件只能在需要的时候从 DOM 里获取表单元素的值。
下面是一个简单的非受控组件示例:
import React, { useRef } from 'react';
// 定义一个名为 UncontrolledInput 的函数组件
function UncontrolledInput() {
// 使用 useRef 钩子创建一个名为 inputRef 的引用对象
const inputRef = useRef(null);
// 定义一个名为 handleSubmit 的函数,用于处理表单提交事件
const handleSubmit = (event) => {
// 阻止表单的默认提交行为
event.preventDefault();
// 通过 inputRef.current.value 获取输入框的值
const value = inputRef.current.value;
// 打印输入框的值
console.log('你输入的内容是:', value);
};
// 渲染一个表单,包含一个输入框和一个提交按钮
// 将 inputRef 引用对象绑定到输入框的 ref 属性上
// 当表单提交时,调用 handleSubmit 函数
return (
<form onSubmit={handleSubmit}>
<input
type="text"
ref={inputRef}
/>
<button type="submit">提交</button>
</form>
);
}
export default UncontrolledInput;
实现原理
非受控组件的实现原理是借助 React 的 ref 来访问 DOM 元素。通过 ref 可以直接获取 DOM 元素的属性和方法,从而在需要的时候获取表单元素的值。
方法
用 useRef 钩子或者类组件的 createRef 方法创建一个 ref 对象。
把 ref 对象绑定到表单元素的 ref 属性上。
在需要的时候,通过 ref 对象的 current 属性来访问 DOM 元素,进而获取表单元素的值。
作用和应用场景
非受控组件适合那些只需要在表单提交时获取表单数据,或者与第三方库集成的场景。比如文件上传表单、简单的表单提交等。
区别
- 数据控制:受控组件的数据由 React 组件的状态控制,非受控组件的数据由 DOM 自己管理。
- 事件处理:受控组件需要为表单元素添加 onChange 事件处理函数来更新状态,非受控组件不需要处理表单元素的值变化事件。
- 数据获取:受控组件可以随时获取表单元素的值,非受控组件只能在需要的时候通过 ref 来获取表单元素的值。
综上所述,受控组件和非受控组件各有优劣,你要根据具体的需求来选择合适的组件类型。
受控组件和非受控组件适用场景
在React中,受控组件和非受控组件分别适用于哪些场景?
在 React 里,受控组件和非受控组件各有特点,适用于不同的应用场景,下面为你详细介绍:
受控组件适用场景
1. 实时验证用户输入
当你需要对用户输入的数据进行实时验证时,受控组件是很好的选择。因为受控组件可以在每次输入变化时触发状态更新,从而能及时对输入内容进行检查。
比如,在一个注册表单里,要求用户输入的密码长度至少为 6 位,一旦用户输入的内容发生变化,就可以立即检查密码长度是否符合要求,并给出相应提示。
import React, { useState } from 'react';
function PasswordInput() {
const [password, setPassword] = useState('');
const [error, setError] = useState('');
const handleChange = (e) => {
const newPassword = e.target.value;
setPassword(newPassword);
if (newPassword.length < 6) {
setError('密码长度至少为 6 位');
} else {
setError('');
}
};
return (
<div>
<input
type="password"
value={password}
onChange={handleChange}
/>
{error && <p style={{ color: 'red' }}>{error}</p>}
</div>
);
}
export default PasswordInput;
2. 根据输入动态更新 UI
如果需要根据用户的输入动态更新页面的其他部分,受控组件可以方便地实现这一功能。因为组件状态的变化可以直接反映到 UI 上。
例如,一个搜索框,用户输入关键词后,页面上会实时显示与关键词匹配的搜索结果。
import React, { useState } from 'react';
const data = ['apple', 'banana', 'cherry', 'date'];
function SearchInput() {
const [searchTerm, setSearchTerm] = useState('');
const handleChange = (e) => {
setSearchTerm(e.target.value);
};
const filteredData = data.filter(item =>
item.toLowerCase().includes(searchTerm.toLowerCase())
);
return (
<div>
<input
type="text"
value={searchTerm}
onChange={handleChange}
placeholder="搜索..."
/>
<ul>
{filteredData.map(item => (
<li key={item}>{item}</li>
))}
</ul>
</div>
);
}
export default SearchInput;
3. 多表单元素联动
当多个表单元素之间存在联动关系时,受控组件可以更好地管理它们之间的数据交互。通过更新状态,可以同时更新多个表单元素的值。
例如,一个包含省份和城市选择的表单,当用户选择不同的省份时,城市下拉列表会相应地更新。
import React, { useState } from 'react';
const provinceCityMap = {
'广东': ['广州', '深圳', '珠海'],
'江苏': ['南京', '苏州', '无锡']
};
function ProvinceCitySelector() {
const [province, setProvince] = useState('');
const [city, setCity] = useState('');
const handleProvinceChange = (e) => {
const newProvince = e.target.value;
setProvince(newProvince);
setCity('');
};
const handleCityChange = (e) => {
setCity(e.target.value);
};
return (
<div>
<select value={province} onChange={handleProvinceChange}>
<option value="">请选择省份</option>
{Object.keys(provinceCityMap).map(p => (
<option key={p} value={p}>{p}</option>
))}
</select>
<select value={city} onChange={handleCityChange} disabled={!province}>
<option value="">请选择城市</option>
{province && provinceCityMap[province].map(c => (
<option key={c} value={c}>{c}</option>
))}
</select>
</div>
);
}
export default ProvinceCitySelector;
非受控组件适用场景
1. 简单表单提交
在一些简单的表单场景中,只需要在表单提交时获取表单数据,而不需要实时跟踪输入变化,非受控组件可以减少代码复杂度。
例如,一个简单的留言表单,用户填写完内容后点击提交按钮,将数据发送到服务器。
import React, { useRef } from 'react';
function MessageForm() {
const messageRef = useRef(null);
const handleSubmit = (e) => {
e.preventDefault();
const message = messageRef.current.value;
console.log('留言内容:', message);
};
return (
<form onSubmit={handleSubmit}>
<textarea ref={messageRef} />
<button type="submit">提交留言</button>
</form>
);
}
export default MessageForm;
2. 与第三方库集成
当需要与一些第三方表单库或插件集成时,非受控组件可以更方便地与这些库进行交互。因为第三方库通常是基于 DOM 操作的,使用 ref 可以直接访问 DOM 元素。
例如,使用一个第三方的富文本编辑器,通过 ref 可以方便地获取编辑器中的内容。
import React, { useRef, useEffect } from 'react';
// 假设这是一个第三方富文本编辑器库
import RichTextEditor from 'some-rich-text-editor-library';
function RichTextInput() {
const editorRef = useRef(null);
useEffect(() => {
const editor = new RichTextEditor(editorRef.current);
// 可以在这里进行更多的编辑器初始化配置
}, []);
const handleSubmit = (e) => {
e.preventDefault();
const content = editorRef.current.getValue();
console.log('富文本内容:', content);
};
return (
<form onSubmit={handleSubmit}>
<div ref={editorRef} />
<button type="submit">提交内容</button>
</form>
);
}
export default RichTextInput;
3. 文件上传
在文件上传场景中,使用非受控组件可以更方便地获取用户选择的文件。因为文件输入框的值不能通过状态来控制,使用 ref 可以直接访问文件输入框的 files 属性。
import React, { useRef } from 'react';
function FileUpload() {
const fileInputRef = useRef(null);
const handleSubmit = (e) => {
e.preventDefault();
const file = fileInputRef.current.files[0];
if (file) {
console.log('选择的文件:', file.name);
}
};
return (
<form onSubmit={handleSubmit}>
<input type="file" ref={fileInputRef} />
<button type="submit">上传文件</button>
</form>
);
}
export default FileUpload;
React vue受控组件与非受控组件区别
那么,与vue受控组件和非受控组件的区别
整体概念差异不大,但实现方式有别
在 React 和 Vue 中,受控组件和非受控组件的核心概念类似,但在具体实现、语法和使用习惯上存在明显差异。
受控组件
React 受控组件
在 React 里,受控组件的数据完全由 React 组件的状态控制。表单元素的值取决于状态,并且任何变化都会触发状态更新。
import React, { useState } from 'react';
function ReactControlledInput() {
// 创建一个状态变量来存储输入框的值,初始为空
const [value, setValue] = useState('');
// 处理输入框变化的函数
const handleChange = (e) => {
// 更新状态变量
setValue(e.target.value);
};
return (
<div>
{/* 输入框的值绑定到状态变量,变化时触发 handleChange 函数 */}
<input type="text" value={value} onChange={handleChange} />
<p>输入内容: {value}</p>
</div>
);
}
export default ReactControlledInput;Vue 受控组件
在 Vue 中,受控组件通常使用 v-model 指令来实现双向数据绑定。v-model 是一个语法糖,它结合了 :value 和 @input 事件。
<template>
<div>
<!-- 使用 v-model 实现双向数据绑定 -->
<input v-model="value" />
<p>输入内容: {{ value }}</p>
</div>
</template>
<script>
export default {
data() {
// 定义一个数据属性来存储输入框的值,初始为空
return {
value: ''
};
}
};
</script>区别总结
- 语法方面:React 需手动绑定 value 属性和 onChange 事件处理函数,而 Vue 用 v-model 指令就能实现双向数据绑定,语法更简洁。
- 数据流向:React 是单向数据流,通过事件处理函数更新状态;Vue 的 v-model 是双向数据绑定,修改表单元素的值会自动更新数据,反之亦然。
非受控组件
React 非受控组件
在 React 中,非受控组件通过 ref 来访问 DOM 元素,从而获取表单元素的值。
import React, { useRef } from 'react';
function ReactUncontrolledInput() {
// 创建一个 ref 对象
const inputRef = useRef(null);
// 处理表单提交的函数
const handleSubmit = (e) => {
e.preventDefault();
// 通过 ref 获取输入框的值
const value = inputRef.current.value;
console.log('输入内容:', value);
};
return (
<form onSubmit={handleSubmit}>
{/* 将 ref 绑定到输入框 */}
<input type="text" ref={inputRef} />
<button type="submit">提交</button>
</form>
);
}
export default ReactUncontrolledInput;Vue 非受控组件
在 Vue 里,非受控组件可通过 ref 来访问 DOM 元素。不过,Vue 更强调数据驱动,使用非受控组件的场景相对较少。
<template>
<form @submit.prevent="handleSubmit">
<!-- 给输入框添加 ref -->
<input type="text" ref="inputRef" />
<button type="submit">提交</button>
</form>
</template>
<script>
export default {
methods: {
handleSubmit() {
// 通过 $refs 获取输入框的值
const value = this.$refs.inputRef.value;
console.log('输入内容:', value);
}
}
};
</script>区别总结
- 语法方面:React 使用 useRef 钩子创建 ref 对象,而 Vue 直接在模板中使用 ref 属性,在脚本里通过 this.$refs 来访问。
- 使用频率:React 里非受控组件的使用较为常见,而 Vue 更倾向于使用数据驱动的方式,非受控组件的使用场景相对较少。
综上所述,React 和 Vue 在受控组件和非受控组件的实现上各有特点,你可以根据项目需求和个人习惯来选择合适的方式。
到此这篇关于React中如何实现受控组件与非受控组件的文章就介绍到这了,更多相关React受控组件与非受控组件内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
