先说一下写着篇文章的契机,是因为回显,复杂表单的回显,让我觉得我对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上有一个有趣的开源项目:FlinkXFlinkX是一个基于Flink的批流统一的数据同步工具,既可以采集静态的数据,也可以采集实时变化的数据,是全域、异构、批流一体的数据同步引擎。大家喜欢的话请给我们点个star!star!star!

github开源项目:https://github.com/DTStack/flinkx

gitee开源项目:https://gitee.com/dtstack_dev_0/flinkx

数栈技术文章分享:你居然是这样的initialValue的更多相关文章

  1. 【codelife 阿里技术文章分享——读后感】

    目前看到的几篇比较有感触的文章,分别是: 前端Leader如何做好团队规划?阿里内部培训总结公开   ——>这里会有关于针对技术项目如何做规划的一些指导,非常有价值 程序员吃的是青春饭?本质上取 ...

  2. Molecule实现数栈至简前端开发新体验

    Keep It Simple, Stupid. 这是开发人耳熟能详的 KISS 原则,也像是一句有调侃意味的善意提醒,提醒每个前端人,简洁易懂的用户体验和删繁就简的搭建逻辑就是前端开发的至简大道. 这 ...

  3. 收藏的技术文章链接(ubuntu,python,android等)

    我的收藏 他山之石,可以攻玉 转载请注明出处:https://ahangchen.gitbooks.io/windy-afternoon/content/ 开发过程中收藏在Chrome书签栏里的技术文 ...

  4. 袋鼠云研发手记 | 开源·数栈-扩展FlinkSQL实现流与维表的join

    作为一家创新驱动的科技公司,袋鼠云每年研发投入达数千万,公司80%员工都是技术人员,袋鼠云产品家族包括企业级一站式数据中台PaaS数栈.交互式数据可视化大屏开发平台Easy[V]等产品也在迅速迭代.在 ...

  5. 让互联网更快:新一代QUIC协议在腾讯的技术实践分享

    本文来自腾讯资深研发工程师罗成在InfoQ的技术分享. 1.前言 如果:你的 App,在不需要任何修改的情况下就能提升 15% 以上的访问速度,特别是弱网络的时候能够提升 20% 以上的访问速度. 如 ...

  6. 袋鼠云研发手记 | 数栈·开源:Github上400+Star的硬核分布式同步工具FlinkX

    作为一家创新驱动的科技公司,袋鼠云每年研发投入达数千万,公司80%员工都是技术人员,袋鼠云产品家族包括企业级一站式数据中台PaaS数栈.交互式数据可视化大屏开发平台Easy[V]等产品也在迅速迭代.在 ...

  7. Jerry的ABAP原创技术文章合集

    我之前发过三篇和ABAP相关的文章: 1. Jerry的ABAP, Java和JavaScript乱炖 这篇文章包含我多年来在SAP成都研究院使用ABAP, Java和JavaScript工作过程中的 ...

  8. 数栈运维实例:Oracle数据库运维场景下,智能运维如何落地生根?

    从马车到汽车是为了提升运输效率,而随着时代的发展,如今我们又希望用自动驾驶把驾驶员从开车这项体力劳动中解放出来,增加运行效率,同时也可减少交通事故发生率,这也是企业对于智能运维的诉求. 从人工运维到自 ...

  9. 袋鼠云出品!数栈UI 5.0全新体验升级,设计背后的故事

    我们是袋鼠云数栈 UED 团队,致力于打造优秀的一站式数据中台产品.我们始终保持工匠精神,探索前端道路,为社区积累并传播经验价值. 前言 数栈作为云原⽣⼀站式⼤数据开发平台,从2016年发布第⼀个版本 ...

  10. SAP成都研究院2018年总共87篇技术文章合集

    2018年很快就要结束了.Jerry在2017年年底准备开始写这个公众号时,给自己定的目标是:2018年至少保证每周发布一篇高质量的文章.如今2018年就快过去了,高质量与否需要大家来反馈,至少从量上 ...

随机推荐

  1. 查看当前linux占用的端口号

    Linux 查看端口占用情况可以使用 lsof 和 netstat 命令. centos 下无法使用lsof命令:"-bash: lsof: command not found"1 ...

  2. DeepSeek 官方推出的实用集成工具百宝箱,建议收藏!

    项目介绍 该实用集成工具百宝箱汇聚了DeepSeek官方精心挑选和推荐的各类集成工具(其中包括:应用程序.AI Agent 框架.AI数据应用框架.RAG 框架.浏览器插件.VS Code 插件等), ...

  3. 如何查看 linux 发行版本

    以 debian 10 buster 为例 有时候我们需要知道当前正在使用的 linux 的发行版本信息...可以通过下面几种方式来查看 使用 lsb_release 命令查看 lsb_release ...

  4. nginx 安装及负载配置

    1.官网下载nginx源码包 http://nginx.org/download/nginx-1.8.1.tar.gz 2.上传到opt目录,解压 cd /opt tar -zxvf nginx-1. ...

  5. Hyperledger Fabric - 自定义network.sh脚本

    引言:依据hyperledger fabric提供的测试网络脚本搭建自己的网络环境 该系列参考:https://blog.csdn.net/ling1998?type=blog 执行./network ...

  6. 如何在 Vim 里直接完成 Git 操作?

    Vim 是 Linux 下一款很常用的文本编辑器,虽然它对初学者而言并不友好,但通过一些插件的配合,它可以被打造成一款很强大的 IDE .良许曾经介绍过三款很常用的插件,可点击以下链接查看: Vim ...

  7. 一文搞懂Dockerfile

    Dockerfile官网 https://docs.docker.com/reference/dockerfile/ 什么是Dockerfile? Dockerfile 是一个文本文件,其内包含了一条 ...

  8. 康谋方案 | 康谋BRICK2与车载以太网设备轻松集成

    导读:在当下,汽车行业在安全性.舒适性.智能和万物互联等方面彻底改变了传统车辆的定义.随着这一趋势,汽车行业逐渐开始采用车载以太网来进行车内数据通讯,比如100Base-T1.1000Base-T1, ...

  9. MySQL 中 DELETE、DROP 和 TRUNCATE 的区别是什么?

    MySQL 中 DELETE.DROP 和 TRUNCATE 的区别 在 MySQL 中,DELETE.DROP 和 TRUNCATE 都是常用于删除数据的操作,但它们在功能.性能.用途和实现方式上有 ...

  10. MySQL 的乐观锁和悲观锁是什么?

    MySQL 的乐观锁和悲观锁是什么? 在并发环境下,为了避免数据竞争和保证数据一致性,可以使用不同的锁策略.乐观锁和悲观锁是两种常见的并发控制机制,它们在锁定数据时的理念和实现方式上有显著区别. 1. ...