数栈技术文章分享:你居然是这样的initialValue
先说一下写着篇文章的契机,是因为回显,复杂表单的回显,让我觉得我对initialValue这个属性是有误解的。
一、initialValue的出处和定义
initialValue的出处:
AntDesign/Form表单件/getFieldDecorator(id,options)装饰器函数/第二个参数options/options.initialValue。
链接地址:https://ant.design/components/form-cn/#getFieldDecorator(id,-options)-%E5%8F%82%E6%95%B0
关于属性initialValue,官方的解释如下:
关键字是“子节点的初始值”,初始值也就是默认值,比如Form中有一个城市的选择器,默认选择“杭州”,那么initialValue就是杭州对应的value。
所以其实我一直以为initialValue是defaultValue一样的存在。
二、initialValue和defaultValue的区别
1. defaultValue的例子
import React, { Component,Fragment } from 'react'; import { Button,Input } from "antd"; export default class CreateFrom extends Component { state={value:"value"} updateValue = () => { this.setState({value:"newValue"}) } render() { return ( <Fragment> <Button onClick={this.updateValue}>更新value</Button> <Input defaultValue={this.state.value} /> </Fragment> ); } }
说明:当该组件被渲染时,Input中的值为”value“,当我点击“更新value按钮”时,Input中的值不更新。
Input组件没有设置value属性的话,就是一个非受控组件,它需要设置defaultValue,如果用户不手动改变Input的输入,那么Input就一直显示defaultValue指向的值(友情提示:值为Input组件第一次被渲染时的真实值,变量或者常量指向的真实值)。这里涉及到了受控组件和非受控组件的知识,不做延伸。
2. intialValue的例子
1)models/list.js
let count = 1; const CITY = ["杭州","北京","上海","广州","深圳"]; export default { namespace: 'list', state: { citys: CITY, detail:{city:CITY[count%5],count} }, effects: { *fetchDetail({ payload }, { call, put }) { // 不发请求,而是直接更新reducer // const response = yield call(service, payload); count++; yield put({ type: 'queryDetail', payload: {city:CITY[count%5],count}, }); }, }, reducers: { queryDetail(state, action) { return { ...state, detail: action.payload, }; } }, };
2)router组件文件
import React, { Component } from 'react'; import { connect } from "dva"; import { InputNumber,Select,Form,Button } from "antd"; const FormItem = Form.Item; const { Option } = Select; const formItemLayout = { labelCol: { xs: { span: 24 }, sm: { span: 2 }, }, wrapperCol: { xs: { span: 24 }, sm: { span: 22 }, }, }; @connect(({list})=>({ citys:list.citys, detail:list.detail })) class CreateFrom extends Component { getDetail = () => { this.props.dispatch({type:"list/fetchDetail"}); } render() { const { form,detail={},citys=[] } = this.props; const { getFieldDecorator } = form; const { city,count } = detail; return ( <Form> <Button onClick={this.getDetail}>重新获取数据</Button> <FormItem {...formItemLayout} label="城市" > {getFieldDecorator('city', { initialValue: city, rules: [{ required: true, message: '请选择城市' }], })( <Select style={{width:160}} placeholder="请选择城市"> { citys.map(item=><Option key={item} value={item}>{item}</Option>) } </Select> )} </FormItem> <FormItem {...formItemLayout} label="总量" > {getFieldDecorator('count', { initialValue:count, rules: [{ required: true, message: '总量(1-99999999)',pattern:/^[1-9][0-9]{0,7}$/ }], })( <InputNumber style={{width:160}}/> )} </FormItem> </Form> ); } } export default Form.create()(CreateFrom);
说明:当该Form组件被渲染时,接收props.detail,因为在models/list.js文件的state中已经初始化,所以,第一次render被渲染的值是“杭州”和“1”,点击“重新获取数据按钮”,这个时候props.detail改变为{city:"北京",count:2},与此同时Form被渲染的值也随之改变。
uhmmm,怎么和defaultValue的表现方式不一样?不是说好是默认值的嘛?不是说好不会跟着数据的改变而改变的嘛?逗我玩还是~
敲黑板,划重点,initialValue值可以被更新,除了下面两种情况:
- 1. 用户手动更新表单数据,比如在<Input />组件中手动输入,在<Select />组件中手动选择等等,在用户手动更新数据之后,initialValue的值改变不会更新表单值。
- 2. 当执行了setFieldsValue方法之后,initialValue的值改变不会更新表单值。
下面的例子中在生命周期函数componentDidMount中执行了setFieldsValue方法,其他不变,你会发现不管怎么点击“重新获取数据按钮”,城市对应的值都不会被更新,而总量对应的值却一直在更新。如果你手动改变总量的输入,再点击“重新获取数据按钮”,此时城市和总量的值都不会被更新。
import React, { Component } from 'react'; import { connect } from "dva"; import { InputNumber,Select,Form,Button } from "antd"; const FormItem = Form.Item; const { Option } = Select; const formItemLayout = { labelCol: { xs: { span: 24 }, sm: { span: 2 }, }, wrapperCol: { xs: { span: 24 }, sm: { span: 22 }, }, }; @connect(({list})=>({ citys:list.citys, detail:list.detail })) class CreateFrom extends Component { componentDidMount(){ this.props.form.setFieldsValue({city:"上海"}); } getDetail = () => { this.props.dispatch({type:"list/fetchDetail"}); } render() { const { form,detail={},citys=[] } = this.props; const { getFieldDecorator } = form; const { city,count } = detail; return ( <Form> <Button onClick={this.getDetail}>重新获取数据</Button> <FormItem {...formItemLayout} label="城市" > {getFieldDecorator('city', { initialValue: city, rules: [{ required: true, message: '请选择城市' }], })( <Select style={{width:160}} placeholder="请选择城市"> { citys.map(item=><Option key={item} value={item}>{item}</Option>) } </Select> )} </FormItem> <FormItem {...formItemLayout} label="总量" > {getFieldDecorator('count', { initialValue:count, rules: [{ required: true, message: '总量(1-99999999)',pattern:/^[1-9][0-9]{0,7}$/ }], })( <InputNumber style={{width:160}}/> )} </FormItem> </Form> ); } } export default Form.create()(CreateFrom);
貌似,表单的回显出现一些转机。。。
三、碎碎念
不要一提表单回显,就使劲往代码里面怼“setFieldsValue”,这样会把代码写得很!很!很!很!很不优雅!!!
超级喜欢《锋利的jQuery》封面上的这句话“每多学一点知识,就少写一行代码”,简直是我写代码的信条。
数栈是云原生—站式数据中台PaaS,我们在github和gitee上有一个有趣的开源项目:FlinkX,FlinkX是一个基于Flink的批流统一的数据同步工具,既可以采集静态的数据,也可以采集实时变化的数据,是全域、异构、批流一体的数据同步引擎。大家喜欢的话请给我们点个star!star!star!
github开源项目:https://github.com/DTStack/flinkx
gitee开源项目:https://gitee.com/dtstack_dev_0/flinkx

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
如何用canvas拍出 jDer's工作照
背景 在京东,就职满五年的老员工被称作“大佬”,如果满了十年,那就要被称之为“超级大佬”了。 从 2016 年 5 月 19 日开始,每一年的这一天都被定为京东集团的“519 老员工日”。正所谓:五年砺银,十年锻金!在京东成长 10 年的员工,放在行业里的任何一家公司,都能够像金子般发光! 在这 5 年或 10 年无数个奋斗的日夜里,大家是以怎样的姿势在工作呢?下面由我揭晓这些姿势是怎样修炼而成的吧~ 玩法 首先我们用一张 gif 图来回顾一下效果 玩法基本的步骤如下 ok,拍完照就可以分享到朋友圈了。 技术选型 可以看到这里用到了大量的图片,通过对图片的拖拽缩放等操作,摆放人物及配件,最终合成相应的图片。那么这一过程是怎么实现的呢? 首先我们采用 NUTUI 来搭建整个项目,其脚手架可以很好地处理图片优化打包等。底部操作菜单模块使用了 NUTUI 中的 Tab 组件,提升了开发效率。在主界面的部分选用了基于 canvas 的 creatjs 库,以及一个轻量级的触屏设备手势库 hammer.js 来开发。 NUTUI NUTUI 是一套京东风格的移动端组件库,开发和服务于移动 Web...
- 下一篇
Flume学习笔记
Flume [fluːm] (引水槽、运河) 王洪亮 2021/05/07 15:05 1. 简介 大数据技术解决的三个问题,海量数据的传输、存储和计算。Flume属于传输框架。专门传输日志的,多媒体不行。 2.安装 官网 http://flume.apache.org/ 下载apache-flume-1.9.0-bin.tar.gz,下载后解压即可,类似tomcat中间件,需要改配置文件 , 把apache-flume-1.9.0-bin/conf/flume-env.sh.template改成flume-env.sh,里面配置jdk地址,安装完毕。 export JAVA_HOME=D:\sde\Java\jdk1.8.0_131 3.Hello Flume样例 flume是按任务启动的,这个任务在flume这里叫agent,每个agent分为三块,source(对接数据来源)、channel(中间缓冲区)、sink(数据去向)。任务过程简述就是从一个地方采集数据后送到其他地方。 此次案例source数据采集自端口,通过channel再经过sink将数据输出到终端屏幕上。 开始编写...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2全家桶,快速入门学习开发网站教程
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- CentOS7,CentOS8安装Elasticsearch6.8.6
- CentOS8编译安装MySQL8.0.19
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Red5直播服务器,属于Java语言的直播服务器