Skip to content

Commit 5cb7178

Browse files
authored
Merge pull request #791 from ShuyunFF2E/fix-datepicker
Fix datepicker
2 parents 0b9587a + 9967d06 commit 5cb7178

1 file changed

Lines changed: 65 additions & 32 deletions

File tree

src/components/datepicker/common/picker.js

Lines changed: 65 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -24,46 +24,58 @@ class Picker extends Component {
2424

2525
this.state = {
2626
currentValue: value ? formatValue(displayNow(new Date(value)), this.format) : defaultTime,
27-
id: Math.random()
28-
.toString()
29-
.replace('.', ''),
27+
id: Math.random().toString().replace('.', ''),
3028
visible: open,
3129
style: {},
3230
prevProps: props,
33-
checkFlag: true // 校验输入的日期格式是否正确
31+
checkFlag: true, // 校验输入的日期格式是否正确
3432
};
3533

3634
this.inpRef = createRef();
3735
this.popupRef = createRef();
3836

3937
this.containerRef = createRef();
4038

41-
this.setYearChild = ref => {
39+
this.setYearChild = (ref) => {
4240
this.yearChild = ref;
4341
};
44-
this.setYearMonthChild = ref => {
42+
this.setYearMonthChild = (ref) => {
4543
this.yearMonthChild = ref;
4644
};
47-
this.setMonthDayChild = ref => {
45+
this.setMonthDayChild = (ref) => {
4846
this.monthDayChild = ref;
4947
};
50-
this.setDateChild = ref => {
48+
this.setDateChild = (ref) => {
5149
this.dateChild = ref;
5250
};
5351
}
5452

5553
static getDerivedStateFromProps(props, prevState) {
5654
const { prevProps } = prevState;
55+
56+
// 如果是初始化状态(没有 prevProps)
57+
if (!prevProps) {
58+
return {
59+
visible: props.open || false,
60+
prevProps: props,
61+
};
62+
}
63+
5764
const { open } = props;
5865
const { open: prevOpen } = prevProps;
5966

67+
// 只有当 open 属性真正发生变化时才更新状态
6068
if (open !== prevOpen) {
6169
return {
6270
visible: open,
63-
prevProps: props
71+
prevProps: props,
6472
};
6573
}
66-
return null;
74+
75+
// 更新 prevProps 但不改变 visible 状态
76+
return {
77+
prevProps: props,
78+
};
6779
}
6880

6981
componentDidMount() {
@@ -76,12 +88,14 @@ class Picker extends Component {
7688
componentDidUpdate(prevProps) {
7789
const { value: prevValue, open: prevOpen } = prevProps;
7890
const { value, open } = this.props;
79-
const { checkFlag } = this.state;
91+
const { checkFlag, visible } = this.state;
8092
if (prevValue !== value) {
8193
const date = checkFlag && value ? displayNow(new Date(value)) : value;
8294
this.handleValueChange(date, false);
8395
}
84-
if (prevOpen !== open) {
96+
97+
// 只有当 open 属性发生变化且与当前 visible 状态不一致时才调用 changeVisible
98+
if (prevOpen !== open && open !== visible) {
8599
this.changeVisible(open);
86100
}
87101
}
@@ -114,7 +128,7 @@ class Picker extends Component {
114128
const { checkFlag } = this.state;
115129
const value = (output && checkFlag) || isClickBtn ? this.props.formatValue(output) : output || '';
116130
this.setState({
117-
currentValue: value ? value.toString().replace(/-/g, '/') : ''
131+
currentValue: value ? value.toString().replace(/-/g, '/') : '',
118132
});
119133
if (isPop) {
120134
this.props.onChange(value);
@@ -154,15 +168,15 @@ class Picker extends Component {
154168
return <DatePicker ref={this.setDateChild} {...this.props} checkValue={transformObj(checkValue)} onChange={this.onPopChange} />;
155169
};
156170

157-
popClick = evt => {
171+
popClick = (evt) => {
158172
evt.stopPropagation();
159173
if (evt.nativeEvent.stopImmediatePropagation) {
160174
evt.nativeEvent.stopImmediatePropagation();
161175
}
162176
};
163177

164178
// 关闭时 校验输入的是否正确
165-
handleClick = e => {
179+
handleClick = (e) => {
166180
const isClickPicker = this.containerRef.current.contains(e.target) || (this.popupRef.current && this.popupRef.current.contains(e.target));
167181
const { checkFlag, visible, currentValue } = this.state;
168182
const { tempMode, formatValue } = this.props;
@@ -188,14 +202,19 @@ class Picker extends Component {
188202
}
189203
};
190204

191-
changeVisible = isVisible => {
205+
changeVisible = (isVisible) => {
206+
// 防止重复设置相同的状态
207+
if (this.state.visible === isVisible) {
208+
return;
209+
}
210+
192211
const { containerRef } = this;
193212
const { id } = this.state;
194213
const { containerEleClass, height, isAppendToBody, className } = this.props;
195214

196215
if (isVisible && id) {
197216
this.setState({
198-
visible: true
217+
visible: true,
199218
});
200219

201220
const style = this.positionPop();
@@ -209,7 +228,7 @@ class Picker extends Component {
209228
containerRef.current,
210229
<div className={`${selectorClass}-popup ${className}`} ref={this.popupRef} onClick={this.popClick}>
211230
{this.renderMainPop()}
212-
</div>
231+
</div>,
213232
);
214233
}
215234

@@ -229,7 +248,7 @@ class Picker extends Component {
229248
}
230249

231250
this.setState({
232-
visible: false
251+
visible: false,
233252
});
234253
this.props.onClose();
235254
destroyDOM(id, containerRef.current);
@@ -248,27 +267,33 @@ class Picker extends Component {
248267
position: 'fixed',
249268
left: isLocationAlignRight ? `${left - (POPUP_WIDTH - width)}px` : `${left}px`,
250269
top: isLocationTop ? `${top - popupHeight}px` : `${bottom}px`,
251-
marginTop
270+
marginTop,
252271
};
253272
}
254273
return {
255274
top: isLocationTop ? `${-popupHeight}px` : `${height}px`,
256275
left: isLocationAlignRight ? '' : '0px',
257276
right: isLocationAlignRight ? '0px' : '',
258-
marginTop
277+
marginTop,
259278
};
260279
};
261280

262-
onClickInput = e => {
281+
onClickInput = (e) => {
263282
e.stopPropagation();
264283
const { disabled } = this.props;
265284
const { visible } = this.state;
266285

267286
if (disabled) return;
268287

269-
// 如果不可见则显示面板
288+
// 修复:无论面板是否可见,都重新激活它以确保正确显示
270289
if (!visible) {
271290
this.changeVisible(true);
291+
} else {
292+
// 先关闭再打开,确保面板能正确响应
293+
this.changeVisible(false);
294+
setTimeout(() => {
295+
this.changeVisible(true);
296+
}, 10);
272297
}
273298
};
274299

@@ -291,9 +316,8 @@ class Picker extends Component {
291316
currentValueTemp.length > lenRule || currentValueTemp.split('/').length > backslashRule + 1 ? currentValue.toString() : currentValueTemp;
292317

293318
this.setState({
294-
currentValue: currentValueFinal
319+
currentValue: currentValueFinal,
295320
});
296-
297321
// 值改变的时候,日历要显示出来
298322
if (!this.state.visible && currentValueFinal) {
299323
this.changeVisible(true);
@@ -303,7 +327,7 @@ class Picker extends Component {
303327
const checkFlag = currentValueFinal ? checkFormat(currentValueFinal.trim(), tempMode, showTimePicker) : true;
304328

305329
this.setState({
306-
checkFlag
330+
checkFlag,
307331
});
308332

309333
// 校验通过 并且有值 日历选择联动
@@ -318,7 +342,16 @@ class Picker extends Component {
318342
const afterV = currentValueFinal.trim().split(' ')[1]; // 拿到年月日时分秒的数值
319343
const dealData = transformObj(currentValueFinal);
320344
// hour: 'other', minute: 'other', second: 'other' 方式時分秒重置,具體看date-picker/grid.js配合使用
321-
this.dateChild.changeCheckValue(afterV ? dealData : { ...dealData, hour: 'other', minute: 'other', second: 'other' });
345+
this.dateChild.changeCheckValue(
346+
afterV
347+
? dealData
348+
: {
349+
...dealData,
350+
hour: 'other',
351+
minute: 'other',
352+
second: 'other',
353+
},
354+
);
322355
// this.dateChild.changeCheckValue( afterV ? dealData : { ...dealData, hour: null, minute: null, second: null } );
323356
}
324357
}
@@ -354,7 +387,7 @@ class Picker extends Component {
354387
// 校验年月日格式是否正确,正确 补全 校验设置为true;不正确 不补全
355388
returnValue = this.props.formatValue(transformObj(formatValue(displayNow(new Date(`${currentValue.trim()} ${defaultTime}`)), this.format)));
356389
this.setState({
357-
currentValue: returnValue
390+
currentValue: returnValue,
358391
});
359392
}
360393

@@ -381,7 +414,7 @@ class Picker extends Component {
381414
'minDate',
382415
'tempMode',
383416
'formatValue',
384-
'integer'
417+
'integer',
385418
]);
386419

387420
return (
@@ -409,7 +442,7 @@ class Picker extends Component {
409442
<div className={`${selectorClass}-popup ${className}`} ref={this.popupRef} style={{ ...style }} onClick={this.popClick}>
410443
{this.renderMainPop()}
411444
</div>,
412-
this.portal
445+
this.portal,
413446
)}
414447
</div>
415448
);
@@ -427,7 +460,7 @@ Picker.propTypes = {
427460
formatValue: PropTypes.func,
428461
onChange: PropTypes.func,
429462
onClose: PropTypes.func,
430-
canEdit: PropTypes.bool
463+
canEdit: PropTypes.bool,
431464
};
432465

433466
Picker.defaultProps = {
@@ -441,7 +474,7 @@ Picker.defaultProps = {
441474
formatValue: noop,
442475
onChange: noop,
443476
onClose: noop,
444-
canEdit: false
477+
canEdit: false,
445478
};
446479

447480
export default Picker;

0 commit comments

Comments
 (0)