jd-opensource / jd-opensource/taro-ui

calendar组件currentDate为空

Open
#1,337 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
4.7k
Forks
740
PR merge metrics
No merged PRs in 30d

Description

**问题描述**

我的需求是取消日历默认选中当前时间;所以我将AtCalendarDefaultProps 的currentDate修改成了可选参数;去掉index.tsx下面的currentDate参数之后;将isMultiSelect设置成true;此时选择范围日期时是从第二次点击开始生效;
**复现步骤**

```js
calenda.d.ts

export interface AtCalendarDefaultProps {
format: string

validDates: Array

marks: Array

currentDate?: Calendar.DateArg | Calendar.SelectedDate

monthFormat: string

hideArrow: boolean

isMultiSelect: boolean

selectedDates: Array
}

index.tsx

import classnames from 'classnames'
import dayjs, { Dayjs } from 'dayjs'
import React from 'react'
import { View } from '@tarojs/components'

import {
AtCalendarDefaultProps,
AtCalendarProps,
AtCalendarPropsWithDefaults,
AtCalendarState,
Calendar,
} from './types/calendar'
import AtCalendarBody from './body/index'
import AtCalendarController from './controller/index'

const defaultProps: AtCalendarDefaultProps = {
validDates: [],
marks: [],
hideArrow: false,
selectedDates: [],
isMultiSelect: false,
format: 'YYYY-MM-DD',
// currentDate: +new Date(),
monthFormat: 'YYYY年MM月',
}

export default class AtCalendar extends React.Component> {
static defaultProps: AtCalendarDefaultProps = defaultProps

public constructor(props: AtCalendarProps) {
super(props)

const { currentDate, isMultiSelect } = props as AtCalendarPropsWithDefaults

this.state = this.getInitializeState(currentDate as Calendar.DateArg, isMultiSelect)
}

public UNSAFE_componentWillReceiveProps(nextProps: AtCalendarProps): void {
const { currentDate, isMultiSelect } = nextProps
if (!currentDate || currentDate === this.props.currentDate) return

if (isMultiSelect && this.props.isMultiSelect) {
const { start, end } = currentDate as Calendar.SelectedDate
const { start: preStart, end: preEnd } = this.props.currentDate as Calendar.SelectedDate

if (start === preStart && preEnd === end) {
return
}
}

const stateValue: AtCalendarState = this.getInitializeState(currentDate, isMultiSelect)

this.setState(stateValue)
}

private getSingleSelectdState = (value: Dayjs): Partial => {
const { generateDate } = this.state

const stateValue: Partial = {
selectedDate: this.getSelectedDate(value.valueOf()),
}

const dayjsGenerateDate: Dayjs = value.startOf('month')
const generateDateValue: number = dayjsGenerateDate.valueOf()

if (generateDateValue !== generateDate) {
this.triggerChangeDate(dayjsGenerateDate)
stateValue.generateDate = generateDateValue
}

return stateValue
}

private getMultiSelectedState = (value: Dayjs): Pick => {
const { selectedDate } = this.state
const { end, start } = this.state.selectedDate

const valueUnix: number = value.valueOf()
const state: Pick = {
selectedDate,
}
if (end) {
state.selectedDate = this.getSelectedDate(valueUnix, 0)
} else {
state.selectedDate.end = Math.max(valueUnix, +start)
state.selectedDate.start = Math.min(valueUnix, +start)
}

return state
}

private getSelectedDate = (start: number, end?: number): Calendar.SelectedDate => {
const stateValue: Calendar.SelectedDate = {
start,
end: start,
}

if (typeof end !== 'undefined') {
stateValue.end = end
}

return stateValue
}

private getInitializeState(
currentDate: Calendar.DateArg | Calendar.SelectedDate,
isMultiSelect?: boolean
): AtCalendarState {
let end: number
let start: number
let generateDateValue: number

if (!currentDate) {
const dayjsStart = dayjs()
start = dayjsStart.startOf('day').valueOf()
generateDateValue = dayjsStart.startOf('month').valueOf()
return {
generateDate: generateDateValue,
selectedDate: {
start: '',
},
}
}

if (isMultiSelect) {
const { start: cStart, end: cEnd } = currentDate as Calendar.SelectedDate

const dayjsStart = dayjs(cStart)

start = dayjsStart.startOf('day').valueOf()
generateDateValue = dayjsStart.startOf('month').valueOf()

end = cEnd ? dayjs(cEnd).startOf('day').valueOf() : start
} else {
const dayjsStart = dayjs(currentDate as Calendar.DateArg)

start = dayjsStart.startOf('day').valueOf()
generateDateValue = dayjsStart.startOf('month').valueOf()

end = start
}

return {
generateDate: generateDateValue,
selectedDate: this.getSelectedDate(start, end),
}
}

private triggerChangeDate = (value: Dayjs): void => {
const { format } = this.props

if (typeof this.props.onMonthChange !== 'function') return

this.props.onMonthChange(value.format(format))
}

private setMonth = (vectorCount: number): void => {
const { format } = this.props
const { generateDate } = this.state

const _generateDate: Dayjs = dayjs(generateDate).add(vectorCount, 'month')
this.setState({
generateDate: _generateDate.valueOf(),
})

if (vectorCount && typeof this.props.onMonthChange === 'function') {
this.props.onMonthChange(_generateDate.format(format))
}
}

private handleClickPreMonth = (isMinMonth?: boolean): void => {
if (isMinMonth === true) {
return
}

this.setMonth(-1)

if (typeof this.props.onClickPreMonth === 'function') {
this.props.onClickPreMonth()
}
}

private handleClickNextMonth = (isMaxMonth?: boolean): void => {
if (isMaxMonth === true) {
return
}

this.setMonth(1)

if (typeof this.props.onClickNextMonth === 'function') {
this.props.onClickNextMonth()
}
}

// picker 选择时间改变时触发

private handleDayClick = (item: Calendar.Item): void => {
const { isMultiSelect } = this.props
const { isDisabled, value } = item

if (isDisabled) return

const dayjsDate: Dayjs = dayjs(value)

let stateValue: Partial = {}

if (isMultiSelect) {
stateValue = this.getMultiSelectedState(dayjsDate)
} else {
stateValue = this.getSingleSelectdState(dayjsDate)
}
this.setState(stateValue as AtCalendarState, () => {
this.handleSelectedDate()
})

if (typeof this.props.onDayClick === 'function') {
const { value, unix, stock } = item
this.props.onDayClick({ value, unix, stock: stock || 0 })
}
}

private handleSelectedDate = (): void => {
const selectDate = this.state.selectedDate
console.log(selectDate)
if (typeof this.props.onSelectDate === 'function') {
const info: Calendar.SelectedDate = {
start: dayjs(selectDate.start).format(this.props.format),
}

if (selectDate.end) {
info.end = dayjs(selectDate.end).format(this.props.format)
}

this.props.onSelectDate({
value: info,
})
}
}

private handleDayLongClick = (item: Calendar.Item): void => {
if (typeof this.props.onDayLongClick === 'function') {
this.props.onDayLongClick({ value: item.value })
}
}

public render(): JSX.Element {
const { generateDate, selectedDate } = this.state
const { validDates, marks, format, minDate, maxDate, className, hideArrow, monthFormat, selectedDates } = this
.props as AtCalendarPropsWithDefaults

return (




)
}
}

// 这里可以贴代码
```

**期望行为**

第一次和第二次点击直接生效
**报错信息**

[

https://user-images.githubusercontent.com/31435496/116528444-6c819500-a90e-11eb-817d-bb33153f4629.MP4

](url)
**系统信息**

**补充信息**

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.