The period of the selection type is rendered very slowly in the CalendarList

44 Views Asked by At

I wanted to use the period selection in the CalendarList, but after clicking the button becomes active after 1-2 seconds. But if you use a regular Calendar, then everything works quickly. This happens regardless of the version of the device and regardless of whether it is iOS or Android

"react-native": "0.72.0" "react-native-calendars": "^1.1299.0"

import dayjs from 'dayjs';
import React, {useMemo, useState} from 'react';
import {SafeAreaView, StatusBar, useColorScheme} from 'react-native';
import {Calendar, CalendarList, DateData} from 'react-native-calendars';

import {MarkedDates, Theme} from 'react-native-calendars/src/types';

function App(): JSX.Element {
  const isDarkMode = useColorScheme() === 'dark';

  const theme: Theme = {
    backgroundColor: '#fff',
    calendarBackground: '#fff',
    selectedDayBackgroundColor: '#4fc030',
    todayTextColor: '#4fc030',
    dayTextColor: '#000',
    textDisabledColor: '#8d8d8d',
    monthTextColor: '#000',
  };

  const [startValue, setStartValue] = useState<any>();
  const [finishValue, setFinishValue] = useState<any>();
  const [periodValue, setPeriodValue] = useState();

  const getDateFromTimestamp = (value: number) =>
    dayjs(value).format('YYYY-MM-DD');

    const getPeriod = (startTimestamp: number, endTimestamp: number) => {
      const period: MarkedDates = {}
    
      let currentTimestamp = startTimestamp
    
      while (currentTimestamp < endTimestamp) {
        const dateString = getDateFromTimestamp(currentTimestamp)
        const startingDay = currentTimestamp === startTimestamp
    
        period[dateString] = {
          color: startingDay ? '#4fc030' : '#4fc03073',
          startingDay,
          customContainerStyle:  { borderRadius: 4 }
        }
    
        currentTimestamp += 24 * 60 * 60 * 1000
      }
    
      period[getDateFromTimestamp(endTimestamp)] = {
        color: '#4fc030',
        endingDay: true,
        customContainerStyle:  { borderRadius: 4 }
      }
    
      return period
    }

    const period = useMemo(() => {
      if (startValue !== undefined && finishValue === undefined) {
        const dateString = getDateFromTimestamp(startValue)
        return {
          [dateString]: {
            color: '#4fc030',
            endingDay: true,
            startingDay: true,
            customContainerStyle: { borderRadius: 4 }
          }
        }
      } else if (finishValue !== undefined && startValue !== undefined) {
        const periodValue = getPeriod(startValue, finishValue)
  
        return periodValue
      }
    }, [startValue, finishValue])
  

     const onDayPress = (dayObj: DateData) => {
    const {day, month, year} = dayObj;

    const timestamp = new Date(year, month - 1, day).getTime();

    console.log('дата нажатия', timestamp);

    if (
      startValue === undefined ||
      (startValue !== undefined && finishValue !== undefined)
    ) {
      setStartValue(timestamp);
      setFinishValue(undefined);
    } else {
      if (startValue > timestamp) {
        setStartValue(timestamp);
        setFinishValue(startValue);
      } else {
        setFinishValue(timestamp);
      }
    }
  };

     console.log(startValue, finishValue);

     return (
    <SafeAreaView>
       <StatusBar barStyle={isDarkMode ? 'light-content' : 'dark-content'} />
      <CalendarList
        minDate={dayjs().format('YYYY-MM-DD')}
        markingType={'period'}
        markedDates={period}
        futureScrollRange={5}
        onDayPress={onDayPress}
        theme={theme}
      />
    </SafeAreaView>
     );
  }

export default App;
0

There are 0 best solutions below