html5 自定义 datepicker,如何使用 React 构建自定义日期选择器(3)

本文作者:IMWeb howenhuo

未经同意,禁止转载

Datepicker 组件

构建 Datepicker 组件

要开始构建 Datepicker 组件,请将以下代码片段添加到 src/components/Datepicker/index.js 文件。

import React from "react";

import PropTypes from "prop-types";

import Calendar from "../Calendar";

import * as Styled from "./styles";

import { isDate, getDateISO } from "../../helpers/calendar";

class Datepicker extends React.Component{

state = { date: null, calendarOpen: false }

toggleCalendar = () => this.setState({ calendarOpen: !this.state.calendarOpen })

handleChange = evt => evt.preventDefault()

handleDateChange = date => {

const { onDateChanged } = this.props;

const { date: currentDate } = this.state;

const newDate = date ? getDateISO(date) : null;

currentDate !== newDate &&

this.setState({ date: newDate, calendarOpen: false }, () => {

typeof onDateChanged === "function" && onDateChanged(this.state.date);

});

}

componentDidMount() {

const { value: date } = this.props;

const newDate = date && new Date(date);

isDate(newDate) && this.setState({ date: getDateISO(newDate) });

}

componentDidUpdate(prevProps) {

const { value: date } = this.props;

const { value: prevDate } = prevProps;

const dateISO = getDateISO(new Date(date));

const prevDateISO = getDateISO(new Date(prevDate));

dateISO !== prevDateISO && this.setState({ date: dateISO });

}

}

Datepicker.propTypes = {

label: PropTypes.string,

value: PropTypes.string,

onDateChanged: PropTypes.func

}

export default Datepicker;

在这里,组件 state 初始化为两个属性:

date:一个 ISO string,表示日期选择器的当前日期。格式是 “YYYY-MM-DD”。

calendarOpen :一个 boolean 标记,表示日期选择器的日历是否可见。

当组件 mount 时,Date 对象从传递给组件 props 的 value 解析,并更新 state,如componentDidMount() 方法所示。

handleDateChange() 方法以 Date 对象作为参数,并更新 state 下的 date。如果 Datepicker 组件的 props 传递了 onDateChanged 回调函数,则将使用更新的 ISO 日期字符串调用该函数。

渲染 datepicker

此时,值得一提的是,Bootstrap Dropdown 组件将用于模拟自定义日期选择器的下拉效果。这就是为什么 Reactstrap 包被添加为此项目的依赖项的原因。

正如您很快会注意到,在日期选择器中渲染的样式化组件是 Reactstrap 下拉组件的样式扩展。

更新 Datepicker 组件以包含 render() 方法,如下面的代码片段所示。

class Datepicker extends React.Component {

// ... other methods here

render() {

const { label } = this.props;

const { date, calendarOpen } = this.state;

return (

{label || 'Enter Date'}

type="text"

value={date ? date.split("-").join(" / ") : ""}

onChange={this.handleChange}

readOnly="readonly"

placeholder="YYYY / MM / DD"

/>

{ calendarOpen && (

)}

);

}

}

Styled.DatePickerFormGroup 组件是一个 Bootstrap 的 .form-group,它包装日期选择器标签和输入字段。需要注意的是,输入字段的类型是 “text”,并且标记为 readonly,这样就无法直接编辑它。还要注意,输入元素上的 change 事件的默认行为已经被阻止。

Styled.DatePickerDropdown 组件及其后代,是 Reactstrap 包 Dropdown 组件的样式扩展。您可以在 这里 了解更多关于 Reactstrap 下拉列表的信息。

最后,Calendar 组件在下拉菜单中渲染,传递 state 中的 date 和 onDateChanged 回调函数的handleDateChange() 方法。

Datepicker 组件最终渲染的 DOM 应该如下所示(带有一些样式):

719bc9310051a06d8016e8633e3eb0fc.png

设置日期选择器的样式

将以下代码片段添加到 src/components/Datepicker/styles.js,以创建日期选择器所需的样式组件。

import styled from 'styled-components';

import { FormGroup, Label, Input, Dropdown, DropdownToggle, DropdownMenu } from 'reactstrap';

export const DatePickerContainer = styled.div`

position: relative;

`;

export const DatePickerFormGroup = styled(FormGroup)`

display: flex;

justify-content: space-between;

position: relative;

width: 100%;

border: 2px solid #06c;

border-radius: 5px;

overflow: hidden;

`;

export const DatePickerLabel = styled(Label)`

margin: 0;

padding: 0 2rem;

font-weight: 600;

font-size: 0.7rem;

letter-spacing: 2px;

text-transform: uppercase;

color: #06c;

border-right: 2px solid #06c;

display: flex;

align-items: center;

justify-content: center;

background: rgba(0, 102, 204, 0.05);

`;

export const DatePickerInput = styled(Input)`

padding: 1rem 2rem;

font-weight: 500;

font-size: 1rem;

color: #333;

box-shadow: none;

border: none;

text-align: center;

letter-spacing: 1px;

background: transparent !important;

display: flex;

align-items: center;

::placeholder {

color: #999;

font-size: 0.9rem;

}

`;

export const DatePickerDropdown = styled(Dropdown)`

position: absolute;

width: 100%;

height: 100%;

top: 0;

left: 0;

`;

export const DatePickerDropdownToggle = styled(DropdownToggle)`

position: relative;

width: 100%;

height: 100%;

background: transparent;

opacity: 0;

filter: alpha(opacity=0);

`;

export const DatePickerDropdownMenu = styled(DropdownMenu)`

position: absolute;

top: 0;

left: 0;

width: 100%;

border: none;

padding: 0;

margin: 0;

transform: none !important;

`;

应用程序组件

最后,更新 src/App.js 文件,看起来像下面的代码片段。

import React, { Component } from "react";

import Datepicker from "./components/Datepicker";

class App extends Component {

render() {

return (

);

}

}

export default App;

如果您按照本文和代码片段进行操作,则应该在 React 应用程序中渲染出一个可用的自定义日期选择器。

结论

在本教程中(1、2、3),您已经能够逐步了解如何构建一个定制的 React 日期选择器组件,该组件可以作为原生 HTML5 日期选择器输入元素的替代。

虽然本教程中创建的自定义日期选择器能按预期工作,但它并不能完全满足日期选择器元素的所有要求。可以进一步改进,例如:

通过 props 实现 max 和 min 日期

将输入类型从 “text” 切换到 “date”

更好的可访问性改进

你可以在 react-datepicker-demo 的 GitHub 上获得这个自定义日期选择器的更多改进版本的完整源代码。 您还可以在 Code Sandbox 上查看演示。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/442513.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

群签名和环签名的区别_超级签名和TF签名使用个人开发者账号的区别是什么?...

了解过当前ios签名的朋友都知道,目前ios签名共分为企业签名、超级签名和TF签名,其中企业签名作为签名行业的“老大哥”,深受各路开发者和App运营商的喜爱。而我们今天的主角却是其他两种:超级签名和TF签名。这两种签名方式与企业签…

matlab水蒸气焓值计算_从第一性原理计算出发来理解含能配合物宏观行为的趋势...

欢迎关注微信公众平台"计算材料学",微信ID:jisuancailiao近日,北京理工大学物理学院郭伟课题组(博士研究生孙矗丽)与北京理工大学爆炸科学与技术国家重点实验室、机电学院张同来课题组在Physical Chemistry …

抖音文字时钟壁纸html,抖音文字时钟app

抖音文字时钟app是一款蛮火蛮有趣的复古罗盘时钟应用,喜欢刷抖音的用户是不是在抖音上看到了这些的时钟,你是不是对这个罗盘产生了兴趣,今天小编为你提供了设置这个时钟的app,当前只有安卓版,苹果版暂未上线&#xff0…

计算机网络十进制转二进制的应用题,【网络-理论】二进制与十进制的转换

由于计算机中运行的数据都是以二进制数的形式存在的,学习二进制数的计算成为计算机专业必备的一门知识。概述正如字面上的意思:二进制数,满二进一,所以说二进制只由 数字0和数字1组成。十进制,满十进一,所以…

最大化_怎样保证油压缓冲器工作效率最大化?

对于油压缓冲器,广大使用者在采购前普遍考虑的是油压缓冲器的价格、质量、品牌。挑选出合适的油压缓冲器仅仅是第一步,提高其工作效率,增加产能,才能为企业创造更多价值。要保证油压缓冲器工作效率最大化,需要做到以下…

aosp 本地版本管理_谈 DevOps 平台实施:我在本地跑明明成功的,为什么在你平台跑就报错?...

我在本地跑明明成功的,为什么在你平台跑就报错?用户在 Jenkins 上跑构建时,失败了,把日志截图给我看,如下图:在过去几个月,每个星期都会有一两个 Jenkins 用户就会给我发送类似的错误日志。这样…

江苏大学2020计算机考研,江苏大学2020年硕士研究生复试时间及主要安排

根据《江苏大学2020年硕士研究生招生复试及录取办法》(江大研〔2020〕3号),为做好我校2020年硕士研究生复试及录取工作,现将有关工作安排通知如下:一、复试人选符合我校复试分数线要求的一志愿考生、符合各学院(中心、研究院、所,…

尼康d7200拍照_为什么尼康和佳能的全画幅旗舰单反却只有2000多万像素?

华为P20Pro摄像头都做到了4000万像素,为什么尼康和佳能的全画幅顶级单反却只有2000多万像素?下面我们先来看看目前市场上摄影器材的像素情况。单机身售价高达3万多的尼康旗舰全画幅单反D5总像素是2133万,有效像素是2082万;单机身售…

国家级一级计算机考试题,国家级计算机一级考试试题

国家级计算机一级考试试题1.在Windows中,打开"资源管理器"窗口后,要改变文件或文件夹的显示方式,应选用( )。CA、"文件"菜单B、"编辑"菜单C、"查看"菜单D、"帮助"菜单2.在Windows的"…

重物码垛搬运机器人_节卡机器人:5G下的智慧物流——柔性生产物流系统

随着经济的发展,制造一直面临着劳动力成本迅速攀升、产能过剩、竞争激烈、客户个性化需求日益增长等问题。另一方面招工难,以及缺乏专业人才,制造业转型迫在眉睫。现在,5G、物联网、协作机器人、机器视觉等新兴技术迅速兴起&#…

霍纳法树形流图中处理机p个数_处理机管理(进程管理)

一、进程1.1.进程的定义程序关于某个数据集合的一次执行过程1.2.进程的特征(与程序比较)结构特征进程控制块(PCB) 程序 数据 进程实体动态性 -- 最基本特征进程:进程实体的一次执行过程,有生命周期程序:程序是一组有序指令的集…

元胞计算机系统,元胞自动机的应用

【定义】元胞自动机(Cellular Automata, CA)定义在一个具有离散、有限状态的元胞组成的元胞空间上,并按照一定的局部规则,在离散的时间维度上演化的动力学系统。【构成】可以视为由一个元胞空间和定义于该空间的变换函数所组成【构形】在某个时刻&#x…

vue获取当前月最后一天_10月的最后一天,有哪些不想谈恋爱适合发朋友圈的文案?...

小时光提醒:今天是10月月的最后一天,凡是遇往,皆为序章。没关系的,不要给自己太大压力,生活不是选择,而是热爱!“慢慢又漫漫,漫漫亦灿灿”我的意思是,所有等待的日子&…

手机psp模拟器哪个好_功能强大,手机微信群控系统和云控哪个好?

互联网信息技术在发展的同时,也在不断刷新我们对新科技的认知。随着微营销发展的风生水起,手机微信群控和云控出现了,主要就是通过一台电脑控制几十上百部手机,场面十分震撼,这样的黑科技,你了解过吗&#…

pandas中size方法_如何使用pdpipe与Pandas构建管道?

作者 | Tirthajyoti Sarkar译者 | 清儿爸编辑 | 夕颜来源 | AI科技大本营(ID: rgznai100)【导读】Pandas 是 Python 生态系统中的一个了不起的库,用于数据分析和机器学习。它在 Excel/CSV 文件和 SQL 表所在的数据世界与 Scikit-learn 或 TensorFlow 施展魔力的建模…

软件测试ipad电池,ipad2020电池有问题是真的吗

ipad2020电池有问题是真的吗?近期,ipad2020电池翻车事件传播的沸沸扬扬,很多人都想退货,也有人说是爱思助手没做适配的问题。如果你担心自己入手的ipad2020电池健康有问题,可以看看本站提供的介绍哦!ipad20…

惯性制导精度是多少_航天装备的命中精度

1航天装备的精度航天装备的精度,即航天装备的命中精度,在打击固定目标时,航天装备命中精度用圆概率偏差(CEP)描述。设P为落点坐标落在以目标为原点R为半径的圆内的概率,当P50%时,R就是圆概率偏差CEP,即航天…

cass生成曲线要素文件_几种常见的CASS字体异常问题,教你如何解决

装了CASS所有字体,命令行还是报错?”“打开图形显示一堆???”“win10系统中细等线等字体显示叹号”与众多CASS初学者的交流中,发现他们最常提的问题之一就是 字体显示异常的问题!SO,…

剑灵傲雪区最新服务器,12.8日势力优化具体内容 各大区服务器互通情况

想必各位剑灵玩家都已经知道了昨天(12.8)的维护更新是为了势力优化,其实也就是合服合区,相同服务器互通了,那么合服合区的具体情况是什么样的呢?一起来看看吧!剑灵迎来了三周年庆典过后的一次大规模合区,虽说是势力优化服务器互通…

cpu 被挂起和阻塞_迄今为止把同步/异步/阻塞/非阻塞/BIO/NIO/AIO讲的这么清楚的好文章...

网上有很多讲同步/异步/阻塞/非阻塞/BIO/NIO/AIO的文章,但是都没有达到我的心里预期,于是自己写一篇出来。常规的误区假设有一个展示用户详情的需求,分两步,先调用一个HTTP接口拿到详情数据,然后使用适合的视图展示详情…