Skip to content
This repository was archived by the owner on Oct 12, 2023. It is now read-only.

Commit 3aad552

Browse files
authored
Refactor components to not use unsafe react methods (#155)
1 parent c9b42c0 commit 3aad552

File tree

6 files changed

+101
-155
lines changed

6 files changed

+101
-155
lines changed

lib/components/Balloon/Balloon.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,10 @@ export class Balloon extends React.Component<BalloonProps, BalloonState> {
7575
};
7676
}
7777

78-
UNSAFE_componentWillReceiveProps(newProps: BalloonProps) {
79-
this.setState({
80-
visible: this.state.hovered || newProps.expanded,
81-
});
78+
static getDerivedStateFromProps(props: BalloonProps, state: BalloonState): Partial<BalloonState> | null {
79+
return {
80+
visible: state.hovered || props.expanded
81+
};
8282
}
8383

8484
shouldComponentUpdate(newProps: BalloonProps, newState: BalloonState): boolean {

lib/components/DateTime/Calendar.tsx

Lines changed: 32 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -78,26 +78,24 @@ export class Calendar extends React.Component<CalendarProps, Partial<CalendarSta
7878
}
7979
};
8080

81-
private value: MethodDate;
8281
private monthNames: string[];
8382
private dayNames: string[];
8483
private _container: HTMLDivElement;
8584
private nextFocusRow?: number;
8685
private nextFocusCol?: number;
8786

88-
8987
constructor(props: CalendarProps) {
9088
super(props);
9189

90+
let currentDate: MethodDate;
9291
if (typeof (this.props.value) === 'string') {
93-
this.value = MethodDate.fromString(this.props.localTimezone, this.props.value);
92+
currentDate = MethodDate.fromString(this.props.localTimezone, this.props.value);
9493
} else if (this.props.value) {
95-
this.value = MethodDate.fromDate(this.props.localTimezone, this.props.value);
94+
currentDate = MethodDate.fromDate(this.props.localTimezone, this.props.value);
9695
} else {
97-
this.value = new MethodDate(this.props.localTimezone);
96+
currentDate = new MethodDate(this.props.localTimezone);
9897
}
9998

100-
let currentDate = this.value.copy();
10199
if (props.year > 0) {
102100
currentDate.year = props.year;
103101
}
@@ -120,33 +118,29 @@ export class Calendar extends React.Component<CalendarProps, Partial<CalendarSta
120118
this.setContainerRef = this.setContainerRef.bind(this);
121119
}
122120

123-
UNSAFE_componentWillReceiveProps(newProps: CalendarProps) {
124-
const date = this.state.currentDate.copy();
121+
static getDerivedStateFromProps(props: CalendarProps, state: CalendarState): Partial<CalendarState> | null {
122+
const date = state.currentDate.copy();
125123
let update = false;
126-
if (newProps.year !== this.props.year && newProps.year > 0) {
127-
date.year = newProps.year;
124+
125+
if (props.year > 0) {
126+
date.year = props.year;
128127
update = true;
129128
}
130-
if (
131-
typeof (newProps.month) === 'number' &&
132-
newProps.month !== this.props.month &&
133-
(newProps.month === 0 || newProps.month > 0)
129+
130+
if (typeof (props.month) === 'number' &&
131+
(props.month === 0 || props.month > 0)
134132
) {
135-
date.month = newProps.month;
133+
date.month = props.month;
136134
update = true;
137135
}
138-
if (update && !this.state.detached && date.isValid()) {
139-
this.setState({ currentDate: date });
140-
}
141-
if (this.props.value !== newProps.value || this.props.localTimezone !== newProps.localTimezone) {
142-
if (typeof (newProps.value) === 'string') {
143-
this.value = MethodDate.fromString(newProps.localTimezone, newProps.value);
144-
} else if (newProps.value) {
145-
this.value = MethodDate.fromDate(newProps.localTimezone, newProps.value);
146-
} else {
147-
this.value = new MethodDate(newProps.localTimezone);
148-
}
136+
137+
if (update && !state.detached && date.isValid()) {
138+
return {
139+
currentDate: date
140+
};
149141
}
142+
143+
return null;
150144
}
151145

152146
componentDidUpdate() {
@@ -283,6 +277,15 @@ export class Calendar extends React.Component<CalendarProps, Partial<CalendarSta
283277
const curYear = this.state.currentDate.year;
284278
const curMonth = this.state.currentDate.month;
285279

280+
let currentDate: MethodDate;
281+
if (typeof (this.props.value) === 'string') {
282+
currentDate = MethodDate.fromString(this.props.localTimezone, this.props.value);
283+
} else if (this.props.value) {
284+
currentDate = MethodDate.fromDate(this.props.localTimezone, this.props.value);
285+
} else {
286+
currentDate = new MethodDate(this.props.localTimezone);
287+
}
288+
286289
const weekdays = this.dayNames.map(day => {
287290
return (
288291
<Attr.div key={day} attr={this.props.attr.weekDayHeader}>
@@ -351,9 +354,9 @@ export class Calendar extends React.Component<CalendarProps, Partial<CalendarSta
351354
if (this.props.value) {
352355
const isSelected = (
353356
this.props.value &&
354-
date === this.value.date &&
355-
col.month === this.value.month &&
356-
col.year === this.value.year
357+
date === currentDate.date &&
358+
col.month === currentDate.month &&
359+
col.year === currentDate.year
357360
);
358361
if (isSelected) {
359362
return (

lib/components/DateTime/DatePicker.tsx

Lines changed: 14 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ export class DatePicker extends React.Component<DatePickerProps, Partial<DatePic
124124
constructor(props: DatePickerProps) {
125125
super(props);
126126

127-
const newState = this.getInitialState(props, '');
127+
const newState = DatePicker.getInitialState(props, '');
128128
this.state = {
129129
...newState,
130130
expanded: false,
@@ -140,23 +140,23 @@ export class DatePicker extends React.Component<DatePickerProps, Partial<DatePic
140140
*
141141
* @param props DatePickerProps
142142
*/
143-
getInitialState(props: DatePickerProps, currentValue: string): DatePickerState {
143+
static getInitialState(props: DatePickerProps, currentValue: string, currentInitialValue?: MethodDate): DatePickerState {
144144
const local = props.localTimezone;
145145
let value = currentValue;
146146
let initialValue: MethodDate = null;
147147
if (props.initialValue) {
148148
if (props.initialValue === 'invalid') {
149-
if (this.state && this.state.initialValue) {
149+
if (currentInitialValue) {
150150
initialValue = MethodDate.fromString(
151151
props.localTimezone,
152-
this.state.initialValue.dateObject.toJSON()
152+
currentInitialValue.dateObject.toJSON()
153153
);
154154
}
155155
} else if (typeof(props.initialValue) === 'string') {
156156
const date = MethodDate.fromString(local, props.initialValue);
157157
if (date && dateIsValid(date.dateObject, local)) {
158158
initialValue = date;
159-
const parsed = this.parse(currentValue);
159+
const parsed = DatePicker.parse(currentValue, props.format, props.localTimezone);
160160
if (
161161
date.year !== parsed.year ||
162162
date.month !== (parsed.month - 1) ||
@@ -203,18 +203,8 @@ export class DatePicker extends React.Component<DatePickerProps, Partial<DatePic
203203
};
204204
}
205205

206-
/**
207-
* Update the Date/Time object used internally with a new initialValue
208-
*
209-
* @param newProps new DatePickerProps
210-
*/
211-
UNSAFE_componentWillReceiveProps(newProps: DatePickerProps) {
212-
if ((this.props.initialValue !== newProps.initialValue || this.props.localTimezone !== newProps.localTimezone) && newProps.initialValue !== 'invalid') {
213-
const newState = this.getInitialState(newProps, this.input.value);
214-
this.setState({
215-
...newState,
216-
});
217-
}
206+
static getDerivedStateFromProps(props: DatePickerProps, state: DatePickerState): Partial<DatePickerState> | null {
207+
return DatePicker.getInitialState(props, state.value, state.initialValue);
218208
}
219209

220210
componentDidMount() {
@@ -227,7 +217,7 @@ export class DatePicker extends React.Component<DatePickerProps, Partial<DatePic
227217
window.removeEventListener('keydown', this.onKeydown);
228218
}
229219

230-
parse(newValue: string) {
220+
static parse(newValue: string, format: DateFormat, localTimezone: boolean) {
231221
let valid = true;
232222

233223
let split = newValue.split('/');
@@ -239,17 +229,17 @@ export class DatePicker extends React.Component<DatePickerProps, Partial<DatePic
239229
}
240230

241231
let year, month, date;
242-
if (this.props.format === DateFormat.DDMMYYYY) {
232+
if (format === DateFormat.DDMMYYYY) {
243233
year = parseInt(split[2]);
244234
month = parseInt(split[1]);
245235
date = parseInt(split[0]);
246236
}
247-
else if (this.props.format === DateFormat.MMDDYYYY) {
237+
else if (format === DateFormat.MMDDYYYY) {
248238
year = parseInt(split[2]);
249239
month = parseInt(split[0]);
250240
date = parseInt(split[1]);
251241
}
252-
else if (this.props.format === DateFormat.YYYYMMDD) {
242+
else if (format === DateFormat.YYYYMMDD) {
253243
year = parseInt(split[0]);
254244
month = parseInt(split[1]);
255245
date = parseInt(split[2]);
@@ -271,7 +261,7 @@ export class DatePicker extends React.Component<DatePickerProps, Partial<DatePic
271261

272262
if (valid) {
273263
let parsed = new MethodDate(
274-
this.props.localTimezone,
264+
localTimezone,
275265
year,
276266
month - 1,
277267
date
@@ -305,7 +295,7 @@ export class DatePicker extends React.Component<DatePickerProps, Partial<DatePic
305295
this.setState({value: newValue});
306296
}
307297
} else {
308-
let result = this.parse(newValue);
298+
let result = DatePicker.parse(newValue, this.props.format, this.props.localTimezone);
309299
if (result.valid) {
310300
const initialValue = this.state.initialValue;
311301
const dateValue = new MethodDate(
@@ -387,7 +377,7 @@ export class DatePicker extends React.Component<DatePickerProps, Partial<DatePic
387377

388378
const placeholder = placeholders[this.props.format];
389379

390-
const parsed = this.parse(this.state.value);
380+
const parsed = DatePicker.parse(this.state.value, this.props.format, this.props.localTimezone);
391381
const inputClassName = css('date-picker-input', {
392382
'error': !!this.props.error || (
393383
!parsed.valid && !!this.props.initialValue

lib/components/DateTime/DateTimeField.tsx

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -133,10 +133,10 @@ export class DateTimeField extends React.Component<DateTimeFieldProps, Partial<D
133133
constructor(props: DateTimeFieldProps) {
134134
super(props);
135135

136-
this.state = this.getInitialState(props);
136+
this.state = DateTimeField.getInitialState(props);
137137
}
138138

139-
getInitialState(props: DateTimeFieldProps): DateTimeFieldState {
139+
static getInitialState(props: DateTimeFieldProps): DateTimeFieldState {
140140
const local = props.localTimezone;
141141
let invalid = false;
142142
let initialValue = null;
@@ -212,10 +212,8 @@ export class DateTimeField extends React.Component<DateTimeFieldProps, Partial<D
212212
};
213213
}
214214

215-
UNSAFE_componentWillReceiveProps(newProps: DateTimeFieldProps) {
216-
if (this.props.initialValue !== newProps.initialValue || this.props.localTimezone !== newProps.localTimezone) {
217-
this.setState(this.getInitialState(newProps));
218-
}
215+
static getDerivedStateFromProps(props: DateTimeFieldProps, _state: DateTimeFieldState): Partial<DateTimeFieldState> | null {
216+
return DateTimeField.getInitialState(props);
219217
}
220218

221219
onDatePaste = (newDate: string): boolean => {

0 commit comments

Comments
 (0)