CalendarPicker
CalendarPicker copied to clipboard
Can't use custom dates styles for selected day
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:
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>
);
},
);
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.
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)
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.
i am still experiening this bug too, has there been a solution?