首页 > 解决方案 > 使用 react-native-calendars,如何将按下的日期传递回 'markedDates' 道具?

问题描述

目标:能够使用prop在日历上选择2个日期react-native-calendarsonDayPress并使用prop中的结果markedDates组成一个天数。

组件.js:

import React, { useState, useEffect } from 'react';
import { Image, View, Animated, StyleSheet, TouchableOpacity, Dimensions } from 'react-native';
import EStyleSheet from 'react-native-extended-stylesheet';
import { Calendar } from 'react-native-calendars';

const { width } = Dimensions.get('window');

const CalendarPicker = (props) => {
    const [ markedDates, setMarkedDates ] = useState({});

    const markDate = (dateString) => {
        setMarkedDates(
            (markedDates[dateString] = {
                endingDay: true,
                color: 'blue'
            })
        );
    };

    useEffect(() => {});

    return (
        <Calendar
            style={{
                width: width * 0.8
            }}
            theme={{
                arrowColor: '#219F75'
            }}
            minDate={Date()}
            onDayPress={({ dateString }) => markDate(dateString)}
            hideArrows={false}
            hideExtraDays={true}
            hideDayNames={false}
            markedDates={markedDates}
            markingType={'period'}
        />
    );
};

export default CalendarPicker;

问题:什么都没有发生。日期未“标记”,但 useState 变量已正确分配数据。想知道它是否是重新渲染的问题?如何解决此问题以将所选日期显示为“已标记”?

标签: react-nativereact-native-calendars

解决方案


根据react-native-calendar当你想突出显示开始和结束之间的日期时,你需要创建markedDates如下,

<Calendar
  markedDates={{
    "2020-01-16": { startingDay: true, color: "green" },
    "2020-01-17": { color: "green" },
    "2020-01-18": { color: "green" },
    "2020-01-19": { endingDay: true, color: "gray" }
  }}
  markingType={"period"}
/>

检查下面的示例代码

import * as React from 'react';
import { View, StyleSheet } from 'react-native';
import { Calendar } from 'react-native-calendars';
import moment from 'moment';

export default class CalendarExample extends React.Component {
    state = {
        markedDates: {},
        isStartDatePicked: false,
        isEndDatePicked: false,
        startDate: ''
    }

    onDayPress = (day) => {
        if (this.state.isStartDatePicked == false) {
            let markedDates = {}
            markedDates[day.dateString] = { startingDay: true, color: '#00B0BF', textColor: '#FFFFFF' };
            this.setState({
                markedDates: markedDates,
                isStartDatePicked: true,
                isEndDatePicked: false,
                startDate: day.dateString,
            });
        } else {
            let markedDates = this.state.markedDates
            let startDate = moment(this.state.startDate);
            let endDate = moment(day.dateString);
            let range = endDate.diff(startDate, 'days')
            if (range > 0) {
                for (let i = 1; i <= range; i++) {
                    let tempDate = startDate.add(1, 'day');
                    tempDate = moment(tempDate).format('YYYY-MM-DD')
                    if (i < range) {
                        markedDates[tempDate] = { color: '#00B0BF', textColor: '#FFFFFF' };
                    } else {
                        markedDates[tempDate] = { endingDay: true, color: '#00B0BF', textColor: '#FFFFFF' };
                    }
                }
                this.setState({
                    markedDates: markedDates,
                    isStartDatePicked: false,
                    isEndDatePicked: true,
                    startDate: ''
                });
            } else {
                alert('Select an upcomming date!');
            }
        }
    }

    render() {
        return (
            <View style={styles.container}>
                <Calendar
                    minDate={Date()}
                    monthFormat={"MMMM yyyy"}
                    markedDates={this.state.markedDates}
                    markingType="period"
                    hideExtraDays={true}
                    hideDayNames={true}
                    onDayPress={this.onDayPress}
                />
            </View>
        );
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: 'rgba(52, 52, 52, 0.8)',
        padding: 20,
        justifyContent: 'center'
    }
});

根据您的要求更改此设置,如果您有任何疑问,请随时提出。

希望这对您有所帮助。


推荐阅读