BugiDev / react-native-calendar-strip

Easy to use and visually stunning calendar component for React Native.
MIT License
936 stars 325 forks source link

Onweekchanged keeps getting called infinetely #278

Closed HamzaIkram2727 closed 3 years ago

HamzaIkram2727 commented 3 years ago

<CalendarStrip style={{ height: 150, paddingTop: 20, paddingBottom: 10 }} markedDates={markedStripObject} calendarHeaderStyle={{ fontFamily: FontFamily.semiBold, fontSize: FontSize.extraLarge }} dateNameStyle={{ fontFamily: FontFamily.regular }} dateNumberStyle={{ fontFamily: FontFamily.regular }} useIsoWeekday={false} updateWeek={false} startingDate={new Date()} onDateSelected={(date) => { console.log("date", date) }} onWeekChanged={(start, end) => { computeChangedAgendaWeek(start,end) }}

              />

Here is my code. The problem is that onWeekChanged keeps getting called infinitely even though I am not changing the week. I am setting markedDates in the callback of onWeekchanged, I guess that is causing the problem, but it shouldn't be called infinitely because updateWeek props is set to false. Can anyone please let me know if I am doing anything wrong.

peacechen commented 3 years ago
startingDate={new Date()}

Your code creates a new starting date on every render. The date may be the same, but the time isn't. Even if the values were identical, it's a new object so it detects a change. You should set the value passed to startingDate outside of the render. This is more of a general React question and should be posted in forums such as StackOverflow.

tungnc3142 commented 3 years ago

<CalendarStrip selectedDate={homeStore.currentDate} onDateSelected={(date) => { homeStore.setCurrentDate(date); }} onWeekScrollEnd={(start, end) => { reactotron.log!('onWeekScrollEnd', start, end); }} onWeekChanged={handleWeekChanged} useIsoWeekday={false} updateWeek={false} // startingDate={a} highlightDateContainerStyle={styles.calendarHighlight} style={styles.calendar} />

Here is my code. I don't set prop startingDate but onWeekChanged callback called infinitely event though changing the week. You can reopen issuse?

peacechen commented 3 years ago
selectedDate={homeStore.currentDate}
onDateSelected={(date) => {
  homeStore.setCurrentDate(date);
}}

Your code is violating React best practices. The onDateSelected callback updates state (homeStore.currentDate) which is then used by selectedDate, thus causing a re-render and infinite loop. Remove the selectedDate prop. The child (CalendarStrip) informs the parent (your code) what the selected date is in the callback and synchronizes them. If you need to set an initial selectedDate, place that in another variable and pass that in as the prop.

CVRamana commented 2 years ago

u can use memoized component for calender strip :-

import * as React from 'react'; import { Text, View, StyleSheet, Platform, } from 'react-native'; import CalendarStrip from 'react-native-calendar-strip'; import moment from 'moment'; import constants from '../constants'; import { vh, vw } from '../constants/Dimensions';

interface CustomCalenderStripProps { _maxDate: any _minDate: any

_end: any
_selectedDate: any
_firstDate: any;
handleWeekChange: any

}

const CustomCalenderStrip = (props: CustomCalenderStripProps) => { return ( <CalendarStrip scrollable={false}

        style={{
            height: Platform.OS === 'ios' ? vh(120) : vh(150),
            width: '100%',
            paddingTop: vh(15),
        }}
        maxDate={props._maxDate}
        minDate={props._minDate}
        //  minDate={state.firstDate}
        //@ts-ignore
        datesBlacklist={[
            moment(),
            {
                start: (props._firstDate),
                //@ts-ignore
                end: (props._end ),
            }
        ]}
        dateNameStyle={[styles.dateText, { fontSize: vw(14) }]}
        //showMonth={false}
        disabledDateOpacity={0.6}
        disabledDateNameStyle={[styles.dateText, { fontSize: vw(14) }]}
        disabledDateNumberStyle={[styles.dateText, { fontSize: vw(14) }]}
        calendarHeaderContainerStyle={{ flexDirection: 'row', paddingLeft: vw(20) }}
        highlightDateNameStyle={[styles.dateText, { fontSize: vw(14) }]}
        highlightDateNumberStyle={[styles.dateText, { fontSize: vw(14) }]}
        calendarColor={constants.colors.transparent}
        calendarHeaderStyle={styles.dateText}
        dateNumberStyle={styles.dateText}
        iconLeftStyle={{ height: vh(20), width: vw(22), tintColor: constants.colors.white, }}
        iconRightStyle={{ height: vh(20), width: vw(22), tintColor: constants.colors.white }}
        dayComponentHeight={Platform.OS === 'ios' ? vh(60) : vh(70)}
        maxDayComponentSize={Platform.OS === 'ios' ? vh(45) : vh(60)}
        selectedDate={props._selectedDate}
        //  onDateSelected={(date: any) =>handleWeekChange(date)}
        onWeekChanged={props.handleWeekChange}
    />
);

};

export default React.memo(CustomCalenderStrip);

  1. Use handleWeekChange function with useCallback hook