翻译 | 玩转 React 表单 —— Refs 的运用
React 提供了两种从 受控组件很重,被展示的值和组件的 state 绑定是它的特性。我们通过执行一个附着在 form 元素上的 (在看到下面的文章之前,如果你只是想看相应的示例代码:请移步这里) 受控组件示例: import React,{ Component } from 'react'; class ControlledCompExample extends Component { constructor() { super(); this.state = { fullName: '' } } handleFullNameChange = (e) => { 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 的值是 受控组件最主要的优势是: 受控组件的缺点是要写大量的代码。你需要通过 props 把 state 属性传递给 form 元素,还需要一个函数来更新这个属性的值。 对于单一表单元素来说这真的不是什么问题 —— 但是如果你需要一个庞大并且复杂的表单(不需要动态渲染或者实时验证),过度使用受控表单会让你书写成吨的代码。 从 form 元素取值的简便的方法是使用
1、文本输入框、数字输入框和选择框使用 <input type="text" ref={input => this.fullName = input} /> 由于该参数是 input 元素本身的别名,你可以随心所欲地为它命名: <input type="number" ref={cashMoney => this.amount = cashMoney} /> 接着你可以拿到该参数,并将它赋值给当前 class 内 选择元素也可以用相同的方法(例如:下拉列表)。 <select ref={select => this.petType = select} name="petType"> <option value="cat">Cat</option> <option value="dog">Dog</option> <option value="ferret">Ferret</option> </select> 选择元素的值可以通过 2、子组件通过 props 传值给父组件通过受控组件,父组件获取子组件的值十分简单 —— 父组件中已经有这个值了(译者注:在父组件中定义)!它被传递给子组件。同时 你可以在我上篇文章的受控组件示例中看到它是如何运行的。 虽然该值已经存在于受控组件的父组件中,但是当使用 要将该值从子组件传给父组件,父组件需要向子组件传递一个 在我们更深入的探讨之前先来看一些代码。 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 组件 input 子组件的值被赋给父组件的 父组件不仅可以访问 input 中的 DOM 节点,还可以在父组件内给节点的值赋值。在上文的第 7 行可以看到例子。一旦表单被提交, input 的值就被设置为 “Got ya!” 。 这种方式有点让人摸不着头脑,所以请仔细揣摩并敲代码实践一下,直至完全理解。 你可能会写出来更好的 radio 和 checkbox 受控组件,但是如果你真的想要用 `ref` ,那么接下来的两部分会帮到你。 3、 Radio 标签集合不像 text 和 number 这类 input 元素,radio 元素是成组出现的。每组中的元素都有相同的 <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”。 由于我们关心的是整个集合的元素,所以给每个单选框设置 可以通过下面的三步来检索出 radio 集合的值:
import React,{ Component } from 'react'; class RefsForm extends Component { handleSubmit = (e) => { e.preventDefault(); // 从 form 中取出节点列表 // 它是一个类数组,没有数组的方法 const { pet } = this.form; // radio 标签集合有 value 属性 // 查看打印出来的数据 console.log(pet,pet.value); } render() { return ( <div> <form onSubmit={this.handleSubmit} ref={form => this.form = 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> </div> ); } } export default RefsForm; 如果你正在用子组件写一个表单也是可行的。尽管组件中会有更多的逻辑,但是从 radio 集合中获取值的方法是不变的。 import React,{ Component } from 'react'; class RefsForm extends Component { handleSubmit = (e) => { e.preventDefault(); // 从 form 中取出节点列表 // 它是一个类数组,没有数组的方法 const { pet } = this.form; // radio 标签集合有 value 属性 // 查看打印出来的数据 console.log(pet,pet.value); } render() { return ( <div> <form onSubmit={this.handleSubmit} ref={form => this.form = form}> <RadioSet setName={'pet'} setOptions={['cat','dog','ferret']} /> <input type="submit" value="Submit" /> </form> </div> ); } } function RadioSet(props) { return ( <div> {props.setOptions.map(option => { return ( <label key={option} style={{textTransform: 'capitalize'}}> {option} <input type="radio" value={option} name={props.setName} /> </label> ) })} </div> ); } export default RefsForm; 4、 Checkbox 标签集合和 radio 标签集合不一样, Checkbox 标签集合可能有多个值。导致获取这些值会比获取 radio 标签集合的值难一些。 可以通过下面的五步来检索出 checkbox 标签集合被选中的值: 1、在
4、使用 import React,{ Component } from 'react'; class RefsForm extends Component { handleSubmit = (e) => { e.preventDefault(); // 从 form 中取出节点列表 // 它是一个类数组,没有数组的方法 const { pet } = this.form; // 把节点列表转换成一个数组 const checkboxArray = Array.prototype.slice.call(pet); // 仅取出被选中的 checkbox const checkedCheckboxes = checkboxArray.filter(input => input.checked); console.log('checked array:',checkedCheckboxes); // 使用 .map() 方法从每个被选中的 checkbox 中把值取出来 const checkedCheckboxesValues = checkedCheckboxes.map(input => input.value); console.log('checked array values:',checkedCheckboxesValues); } render() { return ( <div> <form onSubmit={this.handleSubmit} ref={form => this.form = form}> <label> Cat <input type="checkbox" value="cat" name="pet" /> </label> <label> Dog <input type="checkbox" value="dog" name="pet" /> </label> <label> Ferret <input type="checkbox" value="ferret" name="pet" /> </label> <input type="submit" value="Submit" /> </form> </div> ); } } export default RefsForm; 使用子组件写 checkbox 的方法和上一部分中写 radio 的方法是一样的。 import React,checkedCheckboxesValues); } render() { return ( <div> <form onSubmit={this.handleSubmit} ref={form => this.form = form}> <CheckboxSet setName={'pet'} setOptions={['cat','ferret']} /> <input type="submit" value="Submit" /> </form> </div> ); } } function CheckboxSet(props) { return ( <div> {props.setOptions.map(option => { return ( <label key={option} style={{textTransform: 'capitalize'}}> {option} <input type="checkbox" value={option} name={props.setName} /> </label> ) })} </div> ); } export default RefsForm; 结论如果你不需要: 1、实时监视 form 元素的值(例如:为了基于用户的输入渲染之后的组件) 那么使用 大多数情况下,越过受控组件使用
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |