赤峰建设网站,新网站上线,免费论坛创建官网,中国建筑公司排名一览表这周遇到了一个很诡异但又很合理的需求。掉了一周头发#xff0c;死了很多脑细胞终于上线了。必须总结一下#xff0c;不然对不起自己哈哈哈。
一、需求描述
默认当前日期时间不可清空。
功能
默认时间如下#xff1a; 目的#xff1a;将时间改为 2014-08-01 ~ 2014-08…这周遇到了一个很诡异但又很合理的需求。掉了一周头发死了很多脑细胞终于上线了。必须总结一下不然对不起自己哈哈哈。
一、需求描述
默认当前日期时间不可清空。
功能
默认时间如下 目的将时间改为 2014-08-01 ~ 2014-08-12
antd交互
修改开始时间为 2014-08-01结束时间的时间选择范围首先弹出的是 2014 年 12月 和 2015年1月。 也就是说当改变开始时间后跳转到结束日期时日期选择面板根据当前时间而定的。
但实际上这是非常逆人性化的。
因为当我们修改时间的时候往往第二个时间的修改是依赖于第一个选择的时间的。
需求交互
于是产品就提出了希望选择第二个时间的时候展示的时间范围根据第一个选择的时间而定。 即当修改开始时间为 2014-08-01结束时间的时间选择范围首先弹出的是 2014年 08月 和 2015年 09 月。 好希望我把需求描述清楚了。
文字再解释一遍
比如 当前功能当前选择时间为2015-01-01 至 2015-01-01 修改开始时间为 2014-08-01结束时间的时间选择范围首先弹出的是 2014 年 12月 和 2015年1月。 期待功能 修改开始时间为 2014-08-01结束时间的时间选择范围首先弹出的是 2014年 8月 和 2014年 9 月。
二、解决方法
在看了一天日期组件的api之后我终于找到了 使时间范围自动调整的方法。 那就是在 focus 的时候清空当前时间。
所以解决的思路就很明确了在 onFocus 事件中清空 当前时间。
下面我就在代码中解释思路。
import React, { useEffect, useState } from react;
import ./index.css;
import type { DatePickerProps } from antd;
import { DatePicker, Space } from antd;
import dayjs from dayjs;
import customParseFormat from dayjs/plugin/customParseFormat;
import isBetween from dayjs/plugin/isBetween;
dayjs.extend(customParseFormat);
dayjs.extend(isBetween);const { RangePicker } DatePicker;const dateFormat YYYY/MM/DD;const App: React.FC () {const [rangValue, setRangValue] useState([dayjs(),dayjs().add(2, month)]) as any;const [originValue, setOriValue] useState(rangValue);const onFocus (f: any) {// 获取当前聚焦的值不同的环境可能聚焦的值存的位置不同要打印出来看看哪个属性是当前值const value f.srcElement._value;const isStart dayjs(rangValue[0]).format(dateFormat) dayjs(value).format(dateFormat);// 聚焦在哪一个就清空哪一个setRangValue([isStart ? : rangValue[0], isStart ? rangValue[1] : ]);};// 清空之后如果用户不选择当前时间则当前时间会被清空。 所以要在 blur 的时候 用缓存下来的上次数据去补齐const onBlur (b) {setRangValue([rangValue[0] || originValue[0],rangValue[1] || originValue[1]]);setOriValue(rangValue);};// 用户有两种关闭形式一种是跳转到另一个时间选择框一种是鼠标点击其他区域时间范围选择框自动关掉。于是需要在时间范围选择框关掉的时候再次补齐const onOpenChange (open) {if (!open) {setRangValue([rangValue[0] || originValue[0],rangValue[1] || originValue[1]]);setOriValue(rangValue);}};return (Space directionvertical size{12}RangePickervalue{rangValue}format{dateFormat}onFocus{onFocus}onBlur{onBlur}onOpenChange{onOpenChange}//Space);
};export default App;以上就是这个需求的解决思路但是这个解决方法是存在一些风险的。
即在focus 事件中能否判断出当前focus 的是开始时间还是结束时间。
于是我给antd 官方提了issue希望新增加一个数据去实现该跟随功能或者在onfocus事件中多暴露一个参数。
欢迎大家前去支持 日期组件时间范围动态跟随can rangepicker component provied prop to achieve paneltime dynamically followed pre chosen time · Issue #40680 · ant-design/ant-design · GitHub
三、解决问题过程
讲完了需求解决的思路和风险透露一下我做这个需求的心路历程。
1、需求沟通
首先这个需求其实很小产品用一句话描述。 我看了几遍都没有理解得耗费了10分钟去跟产品沟通他要的交互和效果。
2、看文档
沟通清楚了需求我觉得这个需求很合理antd 应该有支持翻翻文档半小时内就能解决。
3、方法尝试
① 尝试属性defaultpickValue后发现defaultpickvalue 仅在第一次点击的时候生效。
② 尝试 在 onCalendarchange 重新设置 时间更改之后dom 不更新。
③ 尝试 disabledate使除了第一次选择的时间之外的相邻月份外全部disable 无效。
经过了以上三种方式的尝试我 finally 看到了onfocus 属性抱着试一试的属性他生效了
4、收尾
今天也跟同事针对这个问题进行了讨论
问题1 为什么在oncalendarchange 中修改绑定的时间不生效
最后的结论是在oncalendarchange 触发后自动触发了 input 函数的 onChange 而在calendar中改变的时间没有更新onChange 函数拿到的还是旧的值。
也就是说onchange 把 oncalendar 中的修改覆盖了。
问题2 为什么要用兜底这样不绕吗
这个问题很尴尬哈哈哈因为这是业务需求的时间不能清空。 所以需要补齐时间。
5、复盘
其实这个问题的解决过程还是太长了。 一是对api 的熟悉度不高二是缺乏经验无法描述出最核心的问题。
在后面确认使用 onfocus 以后以及探讨问题1 的时候在stackoverflow 发现了一些类似的问题。
比如 reactjs - how to set start or end date of antD rangePicker to empty - Stack Overflow