使⽤函数式组件form表单重新赋值为啥不更新_玩转React表单
——Refs的运⽤
原⽂地址:React Forms: Using Refs
原⽂作者:Loren Stewart
译者:萌萌
校对者:⼩ boy
React 提供了两种从 <form> 元素中获取值的标准⽅法。第⼀种⽅法是实现所谓的受控组件
受控组件 (可以看我博客⾥发表的⽂章) ,第⼆种⽅法是使⽤ React 的 ref 属性。
受控组件很重,被展⽰的值和组件的 state 绑定是它的特性。我们通过执⾏⼀个附着在 form 元素上的 onChange 事件句柄,来更新被展⽰的值。onChange 函数更新 state 属性,进⽽更新 form 元素的值。
(在看到下⾯的⽂章之前,如果你只是想看相应的⽰例代码:请移步这⾥)
受控组件⽰例:
import React, { Component } from 'react';
class ControlledCompExample extends Component {
constructor() {
super();
this.state = {
fullName: ''
}
}
handleFullNameChange = (e) => {
htmlradio的text出不来this.setState({
fullName: e.target.value
})
}
handleSubmit = (e) => {
e.preventDefault();
console.log(this.state.fullName)
}
render() {
return (
<div>
<form onSubmit={this.handleSubmit}>
<label htmlFor="fullName">Full Name</label>
<input
type="text"
value={this.state.fullName}
onChange={this.handleFullNameChange}
name="fullName" />
<input type="submit" value="Submit" />
</form>
</div>
);
}
}
export default ControlledCompExample;
input 的值是 this.state.fullName (在第7⾏和第26⾏)。 onChange 函数是 handleFullNameChange (第 10 - 14 ⾏和第 27 ⾏)。
动态地渲染其他组件。例如:⼀个⽤户在下拉列表中选择
验证⽤户的输⼊ 2、可以根据受控组件的值动态地渲染其他组件
受控组件最主要的优势是: 1、便于验证
的值(如“dog” 或者 “cat” )可以控制在 form 中渲染的其他 form 组件(例如:⼀个设置品种的复选框)
受控组件的缺点是要写⼤量的代码。你需要通过 props 把 state 属性传递给 form 元素,还需要⼀个函数来更新这个属性的值。
对于单⼀表单元素来说这真的不是什么问题 —— 但是如果你需要⼀个庞⼤并且复杂的表单(不需要动态渲染或者实时验证),过度使⽤受控表单会让你书写成吨的代码。
从 form 元素取值的简便的⽅法是使⽤ ref 属性。我们⽤不同的⽅式来应对不同的 form 元素和组件结构,所以这篇⽂章剩下的内容分为以下⼏个部分。
1. ⽂本输⼊框、数字输⼊框和选择框
2. ⼦组件通过 props 传值给⽗组件
3. Radio 标签集合
4. Checkbox 标签集合
1、⽂本输⼊框、数字输⼊框和选择框
使⽤ ref 的最简单的例⼦是⽂本和数字 input 元素。我们在 input 的 ref 属性⾥添加⼀个把 input 本⾝作为参数的箭头函数。我喜欢把参数命名为和元素本⾝⼀样的的名字,就像下⾯的第三⾏那个样⼦:
<input
type="text"
ref={input => this.fullName = input} />
由于该参数是 input 元素本⾝的别名,你可以随⼼所欲地为它命名:
<input
type="number"
ref={cashMoney => this.amount = cashMoney} />
接着你可以拿到该参数,并将它赋值给当前 class 内 this 关键字上挂载的属性(译者注:这⾥的 class 指的是 JSX 所处的 React 组件class)。input(例如: DOM 节点)可以通过 this.fullName 和 this.amount 来读取。它的值可以通过 this.fullName.value 和
this.amount.value 来读取。
选择元素也可以⽤相同的⽅法(例如:下拉列表)。
<select
ref={select => this.petType = select}
name="petType">
<option value="cat">Cat</option>
<option value="dog">Dog</option>
<option value="ferret">Ferret</option>
</select>
选择元素的值可以通过 this.petType.value 获取。
2、⼦组件通过 props 传值给⽗组件
通过受控组件,⽗组件获取⼦组件的值⼗分简单 —— ⽗组件中已经有这个值了(译者注:在⽗组件中定义)!它被传递给⼦组件。同时onChange ⽅法也被传给⼦组件,⽤户通过与 UI 互动(译者注:触发 onChange)来更新该值。
你可以在我上篇⽂章的受控组件⽰例中看到它是如何运⾏的。
虽然该值已经存在于受控组件的⽗组件中,但是当使⽤ ref 的时候却不是这样。使⽤ ref 的时候,该值存在于 DOM 节点⾃⾝当中,必须向上与⽗组件通信。
要将该值从⼦组件传给⽗组件,⽗组件需要向⼦组件传递⼀个 钩⼦ 。然后⼦组件将节点挂载到 钩⼦ 上, 以便⽗组件读取。
在我们更深⼊的探讨之前先来看⼀些代码。
import React, { Component } from 'react';
class RefsForm extends Component {
handleSubmit = (e) => {
e.preventDefault();
console.log('first name:', this.firstName.value);
this.firstName.value = 'Got ya!';
}
render() {
return (
<div>
<form onSubmit={this.handleSubmit}>
<CustomInput
label={'Name'}
firstName={input => this.firstName = input} />
<input type="submit" value="Submit" />
</form>
</div>
);
}
}
function CustomInput(props) {
return (
<div>
<label>{props.label}:</label>
<input type="text" ref={props.firstName}/>
</div>
);
}
export default RefsForm;
通过上⾯的代码,可以看到⼀个 form 组件 RefForm 和⼀个叫做 CustomInput 的 input 组件。通常,箭头函数都是在 input ⾃⾝上⾯,但是从这(15 - 27 ⾏)可以看到它是通过 props 传递的。由于箭头函数存在于⽗组件中,所以 this.firstName 中的 this 指向⽗组件。
input ⼦组件的值被赋给⽗组件的 this.firstName 属性,所以⽗组件可以获得⼦组件的值。现在,⽗组件中的 this.firstName 指的是⼦组件中的 DOM 节点(例如: CustomInput 中的 input)。
⽗组件不仅可以访问 input 中的 DOM 节点,还可以在⽗组件内给节点的值赋值。在上⽂的第 7 ⾏可以看到例⼦。⼀旦表单被提交,
input 的值就被设置为 “Got ya!” 。
这种⽅式有点让⼈摸不着头脑,所以请仔细揣摩并敲代码实践⼀下,直⾄完全理解。
你可能会写出来更好的 radio 和 checkbox  受控组件,但是如果你真的想要⽤ `ref` ,那么接下来的两部分会帮到你。
3、 Radio 标签集合
不像 text 和 number 这类 input 元素,radio 元素是成组出现的。每组中的元素都有相同的 name 属性,就像这样:
<form>
<label>
Cat
<input type="radio" value="cat" name="pet" />
</label>
<label>
Dog
<input type="radio" value="dog" name="pet" />
</label>
<label>
Ferret
<input type="radio" value="ferret" name="pet" />
</label>
<input type="submit" value="Submit" />
</form>
在 “pet” radio 标签集合中有三个选项 —— “cat”、“dog” 和 “ferret”。
由于我们关⼼的是整个集合的元素,所以给每个单选框设置 ref 并不是⼀个好主意。遗憾的是,没有 DOM 节点是包含了 radio 集合的。
三步来检索出 radio 集合的值: 1、在 form 标签上设置 ref (下⾯的第20⾏)。 2、从 form 中取出这个 radio 集合。可以通过下⾯的三步
然后它应该是 pet 集合(下⾯的第9⾏)。
此处返回⼀个节点列表和⼀个值。在这种情况下,这个节点列表包含三个 input 节点和被选中的值。
需要注意的是这个节点列表是个类数组,它没有数组的⽅法。在下⼀部分中还有更多关于这个话题的内容。 3、使⽤ . ⽅法来获取这个集合的值(下⾯的第13⾏)。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。