博客 数栈技术文章分享:你居然是这样的initialValue

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

   小美   发表于 2023-01-20 10:40  283  0

一、initialValue的出处和定义

initialValue的出处:

AntDesign/Form表单件/getFieldDecorator(id,options)装饰器函数/第二个参数options/options.initialValue。

http://dtstack-static.oss-cn-hangzhou.aliyuncs.com/2021bbs/files_user6/article/591f6c7c2b0edd39b80e11ae12cd5e34..png

链接地址:https://ant.design/components/form-cn/#getFieldDecorator(id,-options)-%E5%8F%82%E6%95%B0

关于属性initialValue,官方的解释如下:

http://dtstack-static.oss-cn-hangzhou.aliyuncs.com/2021bbs/files_user6/article/928964b317aaa1c9779d57d003bc6c18..png

关键字是“子节点的初始值”,初始值也就是默认值,比如Form中有一个城市的选择器,默认选择“杭州”,那么initialValue就是杭州对应的value。

所以其实我一直以为initialValue是defaultValue一样的存在。

http://dtstack-static.oss-cn-hangzhou.aliyuncs.com/2021bbs/files_user6/article/6d0666d98ec77c0238a283027ce1f78c..png

 

http://dtstack-static.oss-cn-hangzhou.aliyuncs.com/2021bbs/files_user6/article/1b8c362c68b1db8356238f26bdb95cb5..png

 

二、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被渲染的值也随之改变。

http://dtstack-static.oss-cn-hangzhou.aliyuncs.com/2021bbs/files_user6/article/49193d14cd0890659dd22ea531283c39..png

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);

http://dtstack-static.oss-cn-hangzhou.aliyuncs.com/2021bbs/files_user6/article/8011adf0dffb1a3df4d9199dae4b8ed9..png

貌似,表单的回显出现一些转机。。。

三、碎碎念

不要一提表单回显,就使劲往代码里面怼“setFieldsValue”,这样会把代码写得很!很!很!很!很不优雅!!!

超级喜欢《锋利的jQuery》封面上的这句话“每多学一点知识,就少写一行代码”,简直是我写代码的信条。

 

想了解或咨询更多有关袋鼠云大数据产品、行业解决方案、客户案例的朋友,浏览袋鼠云官网:https://www.dtstack.com/?src=bbs


同时,欢迎对大数据开源项目有兴趣的同学加入「袋鼠云开源框架钉钉技术群」,交流最新开源技术信息,群号码:30537511,项目地址:https://github.com/DTStack

0条评论
社区公告
  • 大数据领域最专业的产品&技术交流社区,专注于探讨与分享大数据领域有趣又火热的信息,专业又专注的数据人园地

最新活动更多
微信扫码获取数字化转型资料
钉钉扫码加入技术交流群