随着React应用开发越来越普遍,对于初入行的童鞋来说,必须先打好基础,再深入学习。
今天分享下在React开发中的小应用:提交输入框input值。这种应用在平时项目中经常遇到,所以对于Web前端开发人员,必须熟练掌握。
利用DOM提供的Event对象的target事件属性取值并提交
import React from 'react'; class InputDemo extends React.Component{ state = { InputValue : "",//输入框输入值 }; handleGetInputValue = (event) => { this.setState({ InputValue : event.target.value, }) }; handlePost = () => { const {InputValue} = this.state; console.log(InputValue,'------InputValue'); //在此做提交操作,比如发dispatch等 }; render(){ return( <div> <input value={this.state.InputValue} onChange={this.handleGetInputValue} /> <button onClick={this.handlePost}>提交</button> </div> ) } } export default InputDemo;
这里的<input />和<button />都是用的html的标签,当然也可以使用Antd的<Input />和<Button />组件,里面的内容是不变的
首先在组件最上方state中定义了InputValue:””,下面<input />里写了value={this.state.InputValue},如果去掉onChange事件,那么这时候输入框里是什么都输入不了的,因为
React认为所有的状态都应该由 React 的 state 控制,只要类似于<input />、<textarea />、<select />这样的输入控件被设置了value值,那么它们的值永远以被设置的值为准。如果值没被改变,value就不会变化
React中要用setState才能更新组件的内容,所以需要监听输入框的onChange事件,获取到输入框的内容后通过setState的方式更新state的InputValue,这样<input />的内容才会实时更新
再说onChange的handleGetInputValue方法,利用了DOM的Event对象的target事件属性:
target 事件属性可返回事件的目标节点(触发该事件的节点),如生成事件的元素、文档或窗口。
利用React的ref访问DOM元素取值并提交
//无状态组件 const InputDemo = () => { let inputValue; const handlePost = (e) => { if (e) e.preventDefault(); const valueTemp = inputValue.value; console.log(valueTemp, '------valueTemp'); //在此做提交操作,比如发dispatch等 }; return ( <div> <form onSubmit={handlePost}> <input ref={input => inputValue = input} /> <button onClick={handlePost}>提交</button> </form> </div> ) }; export default InputDemo;
//有状态组件 import React from 'react'; class InputDemo extends React.Component { handlePost = (e) => { if (e) e.preventDefault(); const valueTemp = this.inputValue.value; console.log(valueTemp, '------valueTemp'); //在此做提交操作,比如发dispatch等 }; render() { return ( <div> <form onSubmit={this.handlePost}> <input ref={input => this.inputValue = input} /> <button onClick={this.handlePost}>提交</button> </form> </div> ) } }; export default InputDemo;
Ref是React 提供给我们的安全访问 DOM 元素或者某个组件实例的句柄。我们可以为元素添加 ref 属性,然后在回调函数中接受该元素在 DOM 树中的句柄,该值会作为回调函数的第一个参数返回。
React利用Antd的Form组件实现表单功能
这个是另外一种方法,一起来了解下:
一、构造组件
1、表单一定会包含表单域,表单域可以是输入控件,标准表单域,标签,下拉菜单,文本域等。
这里先引用了封装的表单域 <Form.Item />
2、使用Form.create处理后的表单具有自动收集数据并校验的功能,但如果不需要这个功能,或者默认的行为无法满足业务需求,可以选择不使用Form.create并自行处理数据。
经过Form.create()包装过的组件会自带this.props.form属性,this.props.form提供了很多API来处理数据,如getFieldDecorator——用于和表单进行双向绑定等。
先展示表单样式:
import React from 'react'; import {Form, Table, Button, Select, Input, DatePicker} from 'antd'; const FormItem = Form.Item; const Option = Select.Option; const {RangePicker} = DatePicker;//获取日期选择控件中的日期范围控件 class UserManage extends React.Component { render() { const columns = [ { title: '联系人', dataIndex: 'userName', key: 'userName', }, { title: '手机号', dataIndex: 'mobile', key: 'mobile', }, { title: '公司名称', dataIndex: 'companyName', key: 'companyName', }, { title: '最近活跃时间', dataIndex: 'lastOnlineTime', key: 'lastOnlineTime', }, { title: '禁言状态', dataIndex: 'status', key: 'status', }, ]; return ( <div> <Form layout="inline" style={{marginBottom: '10px'}}> <FormItem label="最近活跃时间"> <RangePicker style={{width: '255px'}}/> </FormItem> <FormItem label="用户"> <Input type="text" placeholder="公司名称、手机号" style={{width: '155px'}}/> </FormItem> <FormItem label="禁言状态"> <Select defaultValue="全部" style={{width: '155px'}}> <Option value="全部">全部</Option> <Option value="是">是</Option> <Option value="否">否</Option> </Select> </FormItem> <Button type="primary" style={{marginTop: '3px', marginRight: '3px'}}>查询</Button> <Button style={{marginTop: '3px'}}>重置</Button> </Form> <Table columns={columns} /> </div> ) } } export default Form.create()(UserManage)
colums是Table组件的API,columns和Column组件使用相同的API:
dataIndex:列数据在数据项中对应的 key,支持a.b.c的嵌套写法,
key:React 需要的 key,如果已经设置了唯一的dataIndex,可以忽略这个属性。
二、使用getFieldDecorator(id, options) 进行表单交互
1、现在的问题就是如何获取各种查询条件的数据,所以先改写render()里面的代码,getFieldDecorator用于和表单进行双向绑定:
... render(){ const {form} = this.props; const {getFieldDecorator} = form; ... return ( <div> <Form onSubmit={this.handleQuery} layout="inline" style={{marginBottom: '10px'}}> <FormItem label="最近活跃时间"> {getFieldDecorator('lastOnlineTime')(<RangePicker style={{width: '255px'}}/>)} </FormItem> <FormItem label="用户"> {getFieldDecorator('userQueryLike')(<Input type="text" placeholder="公司名称或手机号" style={{width: '155px'}}/>)} </FormItem> <FormItem label="禁言状态"> {getFieldDecorator('status', {initialValue: "全部"})( <Select style={{width: '155px'}}> <Option value="0">全部</Option> <Option value="1">是</Option> <Option value="2">否</Option> </Select>)} </FormItem> <Button type="primary" htmlType="submit" style={{marginTop: '3px', marginRight: '3px'}}>查询</Button> <Button style={{marginTop: '3px'}}>重置</Button> </Form> <Table columns={columns} /*dataSource={(从model取得的数据)}*/ /> </div> ) } ...
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
id | 必填输入控件唯一标志。支持嵌套式的写法。 | string | |
options.getValueFromEvent | 可以把 onChange 的参数(如 event)转化为控件的值 | function(..args) | reference |
options.initialValue | 子节点的初始值,类型、可选值均由子节点决定(注意:由于内部校验时使用 === 判断是否变化,建议使用变量缓存所需设置的值而非直接使用字面量)) |
||
options.normalize | 转换默认的 value 给控件 | function(value, prevValue, allValues): any | – |
options.rules | 校验规则,详细参考Antd官方文档 | object[] | |
options.trigger | 收集子节点的值的时机 | string | ‘onChange’ |
options.validateFirst | 当某一规则校验不通过时,是否停止剩下的规则的校验 | boolean | false |
options.validateTrigger | 校验子节点值的时机 | string|string[] | ‘onChange’ |
options.valuePropName | 子节点的值的属性,如 Switch 的是 ‘checked’ | string | ‘value’ |
2、上面给了表单一个onSubmit事件,当表单提交时执行handleQuery方法:
... class UserManage extends React.Component { //表单查询 handleQuery = (e) => { if (e) e.preventDefault(); const {dispatch, form} = this.props; form.validateFields((err, fieldsValue) => { if (err) return; //获取时间范围的值 const rangeValue = fieldsValue['lastOnlineTime']; const userQueryLike = fieldsValue['userQueryLike']; //获取查询条件 const values = { ...fieldsValue, "lastOnlineTime": (rangeValue && rangeValue.length > 1) ? ([rangeValue[0].format('YYYY-MM-DD'), rangeValue[1].format('YYYY-MM-DD')]) : null, "userQueryLike": userQueryLike ? userQueryLike.trim() : userQueryLike, }; dispatch({ type: "userManageModel/getUserList", payload: { values: values, } }); }); }; ... } ...
在此方法里又调用了form.validateFields校验并获取一组输入域的值与Error,入参fieldsValue就是从表单的FormItem里取到的值,然后使用fieldsValue[‘lastOnlineTime’]这种形式,通过与之前写的getFieldDecorator(‘lastOnlineTime’)产生映射,就获取了单个输入域的值。
总结一下,使用React的Form实现表单功能,必须要使用Form.create(组件),使包装的组件带有this.props.form属性,才能调用form的getFieldDecorator和validateFields方法,getFieldDecorator中的id对应validateFields中的fieldsValue[”];而columns中的dateIndex对应的是从model取到数据json串的键名。
总结
关于提交表单的应用,一共分享了三种方法,大家可以根据您项目中的实际情况,选择使用。