Skip to content

Commit 3133dba

Browse files
committed
CalendarListItem to functional component; CalendarList - pass markedDates only to relevant items
1 parent ebe24d3 commit 3133dba

File tree

2 files changed

+103
-116
lines changed

2 files changed

+103
-116
lines changed

src/calendar-list/index.tsx

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ class CalendarList extends Component<CalendarListProps, State> {
124124

125125
constructor(props: CalendarListProps) {
126126
super(props);
127-
127+
// console.log('ctor');
128128
this.style = styleConstructor(props.theme);
129129

130130
const rows = [];
@@ -158,19 +158,26 @@ class CalendarList extends Component<CalendarListProps, State> {
158158
};
159159
}
160160

161-
componentDidUpdate(prevProps: CalendarListProps) {
161+
componentDidUpdate(prevProps: CalendarListProps, prevState: State) {
162162
const prevCurrent = parseDate(prevProps.current);
163163
const current = parseDate(this.props.current);
164164

165165
if (current && prevCurrent && current.getTime() !== prevCurrent.getTime()) {
166166
this.scrollToMonth(current);
167167
}
168+
169+
// Object.entries(this.props).forEach(([key, val]) =>
170+
// prevProps[key] !== val && console.log(`CalendarList Prop '${key}' changed to ${val}`)
171+
// );
172+
// Object.entries(this.state).forEach(([key, val]) =>
173+
// prevState[key] !== val && console.log(`CalendarList State '${key}' changed to ${val}`)
174+
// );
168175
}
169176

170177
static getDerivedStateFromProps(_: CalendarListProps, prevState: State) {
178+
// console.log('derived state');
171179
const rowClone = prevState.rows;
172180
const newRows = [];
173-
174181
for (let i = 0; i < rowClone.length; i++) {
175182
let val: XDate | string = prevState.texts[i];
176183
// @ts-expect-error
@@ -250,6 +257,7 @@ class CalendarList extends Component<CalendarListProps, State> {
250257
}
251258

252259
onViewableItemsChanged = ({viewableItems}: any) => {
260+
// console.log('onViewableItemsChanged');
253261
function rowIsCloseToViewable(index: number, distance: number) {
254262
for (let i = 0; i < viewableItems.length; i++) {
255263
if (Math.abs(index - parseInt(viewableItems[i].index)) <= distance) {
@@ -291,7 +299,7 @@ class CalendarList extends Component<CalendarListProps, State> {
291299

292300
renderItem = ({item}: any) => {
293301
const {horizontal, calendarStyle, calendarWidth, testID, markedDates, ...others} = this.props;
294-
302+
// NOTE: now only 'item' and 'markedDates' change for the 3 calendar (item.getTime) items
295303
return (
296304
<CalendarListItem
297305
{...others}

src/calendar-list/item.tsx

Lines changed: 91 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
import PropTypes from 'prop-types';
2-
import memoize from 'memoize-one';
32
import XDate from 'xdate';
43

5-
import React, {Component} from 'react';
4+
import React, {useRef, useMemo, useContext} from 'react';
65
import {Text, View} from 'react-native';
76

87
import {Theme} from '../types';
9-
import {extractComponentProps} from '../componentUpdater';
10-
import {formatNumbers, sameMonth} from '../dateutils';
8+
import {formatNumbers} from '../dateutils';
9+
import {getCalendarDateString} from '../services';
1110
import Calendar, {CalendarProps} from '../calendar';
1211
import styleConstructor from './style';
13-
import {getCalendarDateString} from '../services';
12+
import CalendarContext from '../expandableCalendar/Context';
1413

1514
export type CalendarListItemProps = CalendarProps & {
1615
item: any;
@@ -21,120 +20,100 @@ export type CalendarListItemProps = CalendarProps & {
2120
scrollToMonth?: (date: XDate) => void;
2221
};
2322

24-
type CalendarListItemState = {
25-
hideArrows: boolean;
26-
hideExtraDays: boolean;
27-
};
28-
29-
class CalendarListItem extends Component<CalendarListItemProps, CalendarListItemState> {
30-
static displayName = 'CalendarListItem';
31-
32-
static propTypes = {
33-
...Calendar.propTypes,
34-
item: PropTypes.any,
35-
calendarWidth: PropTypes.number,
36-
calendarHeight: PropTypes.number,
37-
horizontal: PropTypes.bool
38-
};
39-
40-
static defaultProps = {
41-
hideArrows: true,
42-
hideExtraDays: true
43-
};
44-
45-
style: any;
46-
47-
constructor(props: CalendarListItemProps) {
48-
super(props);
49-
50-
this.style = styleConstructor(props.theme);
51-
}
52-
53-
shouldComponentUpdate(nextProps: CalendarListItemProps) {
54-
const r1 = this.props.item;
55-
const r2 = nextProps.item;
56-
57-
return !sameMonth(r1, r2) || !!(r2.propBump && r2.propBump !== r1.propBump);
58-
}
59-
60-
onPressArrowLeft = (method: () => void, month: XDate) => {
61-
const {onPressArrowLeft, scrollToMonth} = this.props;
62-
const monthClone = month.clone();
63-
64-
if (onPressArrowLeft) {
65-
onPressArrowLeft(method, monthClone);
66-
} else if (scrollToMonth) {
67-
const currentMonth = monthClone.getMonth();
68-
monthClone.addMonths(-1);
69-
70-
// Make sure we actually get the previous month, not just 30 days before currentMonth.
71-
while (monthClone.getMonth() === currentMonth) {
72-
monthClone.setDate(monthClone.getDate() - 1);
23+
const CalendarListItem = (props: CalendarListItemProps) => {
24+
const {
25+
theme,
26+
item,
27+
scrollToMonth,
28+
horizontal,
29+
calendarHeight,
30+
calendarWidth,
31+
testID,
32+
style: propsStyle,
33+
headerStyle,
34+
onPressArrowLeft,
35+
onPressArrowRight
36+
} = props;
37+
const context = useContext(CalendarContext);
38+
39+
const style = useRef(styleConstructor(theme));
40+
const calendarStyle = useMemo(() => {
41+
return [
42+
{
43+
width: calendarWidth,
44+
minHeight: calendarHeight
45+
},
46+
style.current.calendar,
47+
propsStyle
48+
];
49+
}, [calendarWidth, calendarHeight, propsStyle]);
50+
51+
const _onPressArrowLeft = (method: () => void, month?: XDate) => {
52+
const monthClone = month?.clone();
53+
if (monthClone) {
54+
if (onPressArrowLeft) {
55+
onPressArrowLeft(method, monthClone);
56+
} else if (scrollToMonth) {
57+
const currentMonth = monthClone.getMonth();
58+
monthClone.addMonths(-1);
59+
60+
// Make sure we actually get the previous month, not just 30 days before currentMonth.
61+
while (monthClone.getMonth() === currentMonth) {
62+
monthClone.setDate(monthClone.getDate() - 1);
63+
}
64+
scrollToMonth(monthClone);
7365
}
74-
75-
scrollToMonth(monthClone);
7666
}
7767
};
7868

79-
onPressArrowRight = (method: () => void, month: XDate) => {
80-
const {onPressArrowRight, scrollToMonth} = this.props;
81-
const monthClone = month.clone();
82-
83-
if (onPressArrowRight) {
84-
onPressArrowRight(method, monthClone);
85-
} else if (scrollToMonth) {
86-
monthClone.addMonths(1);
87-
scrollToMonth(monthClone);
69+
const _onPressArrowRight = (method: () => void, month?: XDate) => {
70+
const monthClone = month?.clone();
71+
if (monthClone) {
72+
if (onPressArrowRight) {
73+
onPressArrowRight(method, monthClone);
74+
} else if (scrollToMonth) {
75+
monthClone.addMonths(1);
76+
scrollToMonth(monthClone);
77+
}
8878
}
8979
};
9080

91-
getCalendarStyle = memoize((width, height, style) => {
92-
return [{width, minHeight: height}, this.style.calendar, style];
93-
});
94-
95-
render() {
96-
const {
97-
item,
98-
horizontal,
99-
calendarHeight,
100-
calendarWidth,
101-
testID,
102-
style,
103-
headerStyle,
104-
onPressArrowLeft,
105-
onPressArrowRight,
106-
// @ts-expect-error
107-
context
108-
} = this.props;
109-
const calendarProps = extractComponentProps(Calendar, this.props);
110-
const calStyle = this.getCalendarStyle(calendarWidth, calendarHeight, style);
111-
112-
if (item.getTime) {
113-
return (
114-
<Calendar
115-
{...calendarProps}
116-
testID={testID}
117-
current={getCalendarDateString(item.toString())}
118-
style={calStyle}
119-
headerStyle={horizontal ? headerStyle : undefined}
120-
disableMonthChange
121-
onPressArrowLeft={horizontal ? this.onPressArrowLeft : onPressArrowLeft}
122-
onPressArrowRight={horizontal ? this.onPressArrowRight : onPressArrowRight}
123-
context={context}
124-
/>
125-
);
126-
} else {
127-
const text = formatNumbers(item.toString());
128-
129-
return (
130-
<View style={[{height: calendarHeight, width: calendarWidth}, this.style.placeholder]}>
131-
<Text allowFontScaling={false} style={this.style.placeholderText}>
132-
{text}
133-
</Text>
134-
</View>
135-
);
81+
if (item.getTime) {
82+
return (
83+
<Calendar
84+
{...props}
85+
testID={testID}
86+
current={getCalendarDateString(item.toString())}
87+
style={calendarStyle}
88+
headerStyle={horizontal ? headerStyle : undefined}
89+
disableMonthChange
90+
onPressArrowLeft={horizontal ? _onPressArrowLeft : onPressArrowLeft}
91+
onPressArrowRight={horizontal ? _onPressArrowRight : onPressArrowRight}
92+
context={context} // ???
93+
/>
94+
);
95+
} else {
96+
const text = formatNumbers(item.toString());
97+
return (
98+
<View style={[{height: calendarHeight, width: calendarWidth}, style.current.placeholder]}>
99+
<Text allowFontScaling={false} style={style.current.placeholderText}>
100+
{text}
101+
</Text>
102+
</View>
103+
);
136104
}
137-
}
138-
}
105+
};
139106

140107
export default CalendarListItem;
108+
CalendarListItem.displayName = 'CalendarListItem';
109+
CalendarListItem.propTypes = {
110+
...Calendar.propTypes,
111+
item: PropTypes.any,
112+
calendarWidth: PropTypes.number,
113+
calendarHeight: PropTypes.number,
114+
horizontal: PropTypes.bool
115+
};
116+
CalendarListItem.defaultProps = {
117+
hideArrows: true,
118+
hideExtraDays: true
119+
};

0 commit comments

Comments
 (0)