博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Ant Design中DatePicker设置mode="year"无法获取value及关闭面板的解决方案
阅读量:6246 次
发布时间:2019-06-22

本文共 3056 字,大约阅读时间需要 10 分钟。

1、前情提要

当初还是antd2.X版本时,DatePicker组件还不支持mode属性,不能单独设置为年份选择器。但是公司项目刚好很多地方都有根据年份做筛选的需求,因为antd不支持,因此,使用了Select组件来实现年份选择。

但是,遭到了客户的强烈吐槽,“你们这个UI风格还是要一致撒”,哈哈?,官方吐槽最为致命!没办法了,我自己也没法说服自己了,只能照着antd的UI风格自己撸一个YearPicker咯。(时间选择控件YearPicker基于Reactantd )但是,老实说,效果不怎么理想,只能说实现了UI风格的一致,以及值的选择。但是,组件值的清除、动画过渡效果等都没有深入处理。

庆幸的是,很快antd3.X终于支持了年份选择。设置mode="year"便可以使用年份选择器。真是普天同庆!?

2、问题描述

话不多说,赶紧用起来!上代码,

import React, { Component } from 'react';import { DatePicker } from 'antd';export default class extends Component {  onChange = val => {    console.log(val)  }     render() {    return (        
); } }复制代码

界面呈现出只有年份的选择器,nice!❤️❤️

但是,接下来,你就直接懵了。因为不管你怎么点击按钮选择年份都不会起作用,onChange事件根本不会触发,所以value获取不了!

哇,好气哦 !??

百思不得其解,然后去翻看ant designgithub issue。终于看到一条中肯的comment

{console.log(v)}}/>复制代码

只需要把onChange换成onPanelChange就好了。于是可以愉快的获取时间了。

然而,另一个问题出现了,时间虽然是获取了,但是面板并没有关闭。??

继续查找问题,发现当DatePicker变为受控后,需要open这个属性控制面板的关闭。

这个大概是antd团队没考虑到??️?️

import React, { Component } from 'react';import { DatePicker } from 'antd';export default class extends Component {  state =  {    isopen: false,    time: null  }    render() {    const { isopen, time } = this.state    return (        
{this.setState({isopen: true})}} onBlur={() => {this.setState({isopen: false})}} onPanelChange={(v) => { console.log(v) this.setState({ time: v, isopen: false }) }}/>
); } }复制代码

同时,通过onFocusonBlur控制获取焦点和失焦时面板的显隐。

一切似乎很完美,能够获取值,也能正常关闭面板。

然而,快乐的时光总是短暂的,很快,测试便提出缺陷,“这个年份选择器为什么选择完年份后会有闪开闪关的效果,不符合要求哈”

“?,哦,那我再看看呢”

还真的是会闪,明明记得之前没有这个问题啊,算了继续看看问题在哪儿吧。

3、解决方案

查看文档,发现DatePicker有个onOpenChange方法,是这样描述的:弹出日历和关闭日历的回调,function(status)

所以,可以通过onOpenChange方法判断当前的操作是要面板关闭还是打开,来控制面板的显隐。

所以,综上所有的思考,解决思路如下:

1、onChange方法无法触发获取到值,需要换成onPanelChange

2、面板的显示隐藏需要open属性进行手动控制

3、onFocusonBlur会导致闪开闪关,需要换成onOpenChange

import React, { Component } from 'react';import { DatePicker } from 'antd';export default class extends Component {  state =  {    isopen: false,    time: null  }    render() {    const { isopen, time } = this.state    return (        
{ if(status){ this.setState({isopen: true}) } else { this.setState({isopen: false}) } }} onPanelChange={(v) => { console.log(v) this.setState({ time: v, isopen: false }) }} /> onChange={() => { this.setState({time: null}) }}
); } }复制代码

现在可以正常获取值,并且开关面板流畅,不会出现闪开闪关的效果。当然,细心你可能发现一个秘密,就是我在组件中用到了onChange事件,并且做了对值置空的操作。

注意:这里的time置空一定要设置为null。因为组件接受的是一个对象。

这是为什么呢?

我们都知道DatePicker组件有一个allowClear属性,让我们可以通过点击输入框中的❌icon来清除选择的值。

但是当我们设置mode=“year”后,这个allowClear便不起作用了。怎么办呢?

因为onChange事件不会在选择值的时候触发,但是点击清除icon 却会触发。因此通过onChange事件便可以达到清除value的效果。

ok,完美解决~ ??

转载于:https://juejin.im/post/5cf65c366fb9a07eca6968f9

你可能感兴趣的文章
svn解决与优化帮助
查看>>
SQL update select结合语句详解及应用
查看>>
[转]阿里要走102年,阿里的工程师能走多远呢?
查看>>
《算法导论》读书笔记之第15章 动态规划—最长公共子序列
查看>>
从$a_n=f(n)$的角度理解数列中的表达式$a_{n+1}=\frac{k}{a_n}$
查看>>
Redis以及Redis的php扩展安装无错版
查看>>
总结性博客作业
查看>>
Windows Phone 8初学者开发—第11部分:设置SounBoard应用程序
查看>>
欧拉图和哈密顿图
查看>>
解线性方程组
查看>>
Python:pandas之DataFrame常用操作
查看>>
Appium移动自动化测试之—基于java的iOS环境搭建
查看>>
NOIP前的刷题记录
查看>>
洛谷P1973 [NOI2011]Noi嘉年华(决策单调性)
查看>>
书签(Bookmarks)
查看>>
Java 信号量 Semaphore 介绍
查看>>
Ubuntu常用软件安装与使用
查看>>
Anroid开发中常用快捷键
查看>>
RecyclerView分隔线定制
查看>>
文本处理(CSS,JS)
查看>>