form 是网页开发中使用最多的HTML元素之一。自从引入React后,表单的处理方式发生了很多变化。
在React中,有两种方式来处理我们组件中的表单数据。第一种方式是通过使用组件内的状态来处理表单数据。这被称为受控组件。第二种方式是让DOM在组件中自己处理表单数据。这被称为不受控组件。
在本教程中,我们将解释React中受控和非受控组件的区别。我们还将通过实际的例子来演示这两种组件是如何工作的。
什么是React中的受控组件?
React中的受控组件是那些表单数据由组件的状态来处理的组件。
表单是用来在文档部分存储信息的。这个表单的信息通常会被发送到服务器上以执行一个动作。这些数据由表单输入元素和控制元素持有,如input,select,textarea 等,这些元素保持和控制它们的状态或值。
我这么说是什么意思?
每个表单元素都包含一个值。这个值可以由用户或浏览器输入(input,textarea )或选择(checkbox,select,radiobutton, 等等)。当元素的值发生变化时(由键入或选择行为触发),它就会被相应地更新。
你可以在一个元素的HTMLElement 实例中使用.value 属性获得该元素的值。你也可以使用.value 属性来设置表单元素的值。
现在我们可以在我们的组件中使用状态来保持或管理表单元素中的值。下面是一个例子。
function App() {
const [name, setName] = useState("");
const [email, setEmail] = useState("");
function onSubmit() {
console.log("Name value: " + name);
console.log("Email value: " + email);
}
return (
<form onSubmit={onSubmit}>
<input
type="text"
name="name"
value={name}
onChange={(e) => setName(e.target.value)}
required
/>
<input
type="email"
name="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
required
/>
<input type="submit" value="Submit" />
</form>
);
}
这里我们有两个状态:name 和email 。这些状态被分配给name 和email 输入元素的value 属性。
name 状态持有name 输入元素的值。当在name 输入中输入一个值时,附加在它上面的onChange 事件使用setName 更新器函数将输入的值设置为name 状态。
email 状态保存着email 输入元素的值。附在email 输入上的onChange 事件通过setEmail() 改变email 状态,以保持输入元素的值。
正如你所看到的,我们的输入元素name 和email 的值是由 React 状态控制的;状态成为输入元素的 "单一真理源"。因此,上面显示的App 组件是一个受控组件。
使用受控组件的缺点是,随着更多的控制元素被添加到表单元素中,组件中的状态数量会增加。
什么是React中的不受控组件?
不受控制的组件是那些表单数据由DOM本身处理的组件。"不受控制 "是指这些组件不受React状态的控制。
传统上,表单元素的值是由DOM控制并存储在DOM上。我们将不得不引用表单元素的实例来从DOM中检索它们的值。
function App() {
function onSubmit() {
console.log("Name value: " + window.name.value);
console.log("Email value: " + window.email.value);
}
return (
<form onSubmit={onSubmit}>
<input type="text" name="name" id="name" required />
<input type="email" name="email" id="email" required />
<input type="submit" value="Submit" />
</form>
);
}
在上面的代码中,我们给name 和email 输入元素分配了ID属性,其值分别为name 和email 。当表单被提交时,我们使用这些id 属性来获取输入元素的值。
上述组件是一个不受控制的组件,因为React对表单输入元素的值没有控制。
在这个例子中,我们直接使用了DOM APIs。现在让我们重构代码,用React的方式来做。
function App() {
const nameRef = useRef();
const emailRef = useRef();
function onSubmit() {
console.log("Name value: " + nameRef.current.value);
console.log("Email value: " + emailRef.current.value);
}
return (
<form onSubmit={onSubmit}>
<input type="text" name="name" ref={nameRef} required />
<input type="email" name="email" ref={emailRef} required />
<input type="submit" value="Submit" />
</form>
);
}
我们创建了两个React refs,nameRef 和emailRef ,并将它们分别分配给name 和email 输入的ref 属性。这将导致refs ,在它们的.current 属性中持有元素的HTMLElement 实例。从.current ,我们可以引用.value 属性来获得输入元素的值。
受控组件与非受控组件。关键区别
现在我们了解了什么是React受控和非受控组件,让我们回顾一下它们之间的一些关键区别。
- 受控组件是可预测的,因为表单元素的状态是由组件处理的。
- 不受控制的组件是不可预测的,因为在组件的生命周期中,表单元素可能会失去它们的参考,并可能被其他来源改变/影响。
- 受控组件使你能够有效地对你的表单进行表单验证。什么改变表单元素并不重要。他们的值在我们的本地状态中是安全的,所以我们在那里进行验证。
- 使用受控组件,你可以很好地控制表单元素的值。你可以决定它们的走向,以及哪些可以插入,哪些不能插入。
那么,你应该在你的React项目中使用哪一种?问题不在于受控组件和非受控组件是否更好,而在于哪个更适合你的用例,符合你的个人偏好。显然,受控组件能让你对数据有更多的控制,但如果你更喜欢在你的项目中使用非受控组件,那就更适合你了。
没有明确的规则来帮助你确定何时以及如何在React中使用非控制组件和控制组件;这完全取决于你想对你的输入有多少控制。
总结
在本教程中,我们放大了表单元素和表单数据,无论是一般的还是在React框架内。接下来,我们介绍了在React组件中处理表单数据的两种方法:受控和非受控。最后,我们深入研究了这两种类型的组件,并通过实际例子演示了它们的行为。
The postControlled vs. uncontrolled components in Reactappeared first onLogRocket Blog.