stephy / CalendarPicker

CalendarPicker Component for React Native
802 stars 371 forks source link

Can't use custom dates styles for selected day #226

Open listiani13 opened 4 years ago

listiani13 commented 4 years ago

Bug Details Use customDatesStyles to style the selectedDate But I couldn't get it to work as customDatesStyles will always receive the previous state instead of the current one.

Expected Behavior: The font color of selected date will be red, the rest will be pink

Screen Record: Kapture 2020-08-12 at 10 11 45

To Reproduce

export const CalendarPicker: React.FC<Props> = React.memo(
  ({ ...props }) => {
    const [selectedDate, setSelectedDate] = useState<null | moment.Moment>(
      null,
    );
    const onDateChange: DateChangedCallback = (date) => {
      setSelectedDate(date);
    };
    const customDatesStyles = (date: moment.Moment) => {
      if (date.isSame(selectedDate)) {
        return {
          textStyle: {
            color: 'red',
          },
        };
      }
      return {
        textStyle: {
          color: 'pink',
        },
      };
    };

    return (
      <View {...props}>
        <CalendarPicker
          onDateChange={onDateChange}
          customDatesStyles={customDatesStyles}
        />
        <Text>
          Selected Date: {selectedDate?.toString() ?? 'empty'}
        </Text>
      </View>
    );
  },
);
peacechen commented 4 years ago

You're passing a callback to the customDatesStyles prop. That should evaluate each day of the month by invoking your callback. I'm not sure how the previous state comes into play in this scenario.

This line only looks at a single selected date:

if (date.isSame(selectedDate))

It sounds like you need to maintain an array of selected dates so that your customDatesStyles can match on all of them.

listiani13 commented 4 years ago

Hi @peacechen , sorry there was a miss, I was trying to do the multi-marked dates but didn't get it working, so I tried implementing single selected date, but the bug remains the same. As you can see, when I select the day, the text color should be red, but instead it updates the previous selected day. I don't know why, but the selectedDate inside the customDatesStyles is always the previous selectedDate (been trying to log that)

peacechen commented 4 years ago

That looks like a potential race condition. When the selected date changes, your callback updates state with setSelectedDate(date). The state update happens asynchronously, so if the re-render happens before the state settles, it will still see the old selected date. Set breakpoints in your onDateChange and customDatesStyles callbacks to observe the order of events.

One option you could try to enforce the order you need is to pass the selected date prop:

      <CalendarPicker
          selectedStartDate={selectedDate}
          onDateChange={onDateChange}
          customDatesStyles={customDatesStyles}
      />

That may introduce side effects that you'll need to manage.

HugoChengMyC commented 3 years ago

i am still experiening this bug too, has there been a solution?