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

栏目: IOS · Android · 发布时间: 6年前

内容简介:接着上一篇:要开始构建在这里,组件 state 初始化为两个属性:

接着上一篇: 如何使用 React 构建自定义日期选择器(2)

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 (
      <Styled.DatePickerContainer>

        <Styled.DatePickerFormGroup>

          <Styled.DatePickerLabel>{label || 'Enter Date'}</Styled.DatePickerLabel>

          <Styled.DatePickerInput
            type="text"
            value={date ? date.split("-").join(" / ") : ""}
            onChange={this.handleChange}
            readOnly="readonly"
            placeholder="YYYY / MM / DD"
          />

        </Styled.DatePickerFormGroup>

        <Styled.DatePickerDropdown isOpen={calendarOpen} toggle={this.toggleCalendar}>

          <Styled.DatePickerDropdownToggle color="transparent" />

          <Styled.DatePickerDropdownMenu>
            { calendarOpen && (
              <Calendar date={date && new Date(date)} onDateChanged={this.handleDateChange} />
            )}
          </Styled.DatePickerDropdownMenu>

        </Styled.DatePickerDropdown>

      </Styled.DatePickerContainer>
    );
  }

}

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

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

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

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

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

设置日期选择器的样式

将以下代码片段添加到 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 (
      <div className="w-25 py-5 my-5 mx-auto">
        <Datepicker label="Birthday" value="2000-08-15" />
      </div>
    );
  }
}

export default App;

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

结论

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

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

  • 通过 props 实现 maxmin 日期
  • 将输入类型从 “text” 切换到 “date”
  • 更好的可访问性改进

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


以上所述就是小编给大家介绍的《如何使用 React 构建自定义日期选择器(3)》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

深入体验Java Web开发内幕

深入体验Java Web开发内幕

张孝祥 / 电子工业出版社 / 2007-12 / 55.00元

《深入体验Java Web开发内幕:高级特性》是《深入体验Java Web开发内幕——核心基础》的姊妹篇,Java Web开发的初学者在阅读《深入体验Java Web开发内幕:高级特性》前,应该先学习《深入体验Java Web开发内幕——核心基础》。《深入体验Java Web开发内幕:高级特性》详细阐述了Java Web应用开发中的各种高级特性——Apache文件上传组件的源码分析及应用和编写原理......一起来看看 《深入体验Java Web开发内幕》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

随机密码生成器
随机密码生成器

多种字符组合密码

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器