react-native-paper-dates日期输入自动格式化及键盘问题求助
react-native-paper-dates日期输入格式化问题
问题现象
- 日期输入无法自动插入斜杠(/),且虚拟键盘无斜杠按键,无法手动输入
MM/DD/YYYY格式日期 - 仅输入满10位数字时,才会被自动格式化为
MM/DD/YYYY样式(例如输入1234567891会转换为01/14/7892)
相关代码
import React, {Component} from 'react'; import {View, StyleSheet, Text} from 'react-native'; import {Button, Provider as PaperProvider} from 'react-native-paper'; import 'intl'; import 'intl/locale-data/jsonp/en'; import dayjs from 'dayjs'; import {DatePickerModal, TimePickerModal} from 'react-native-paper-dates'; import NewRow from './NewRow'; import {fontSize} from '../resources/fontSize'; import {colors} from '../resources/colors'; import {theme} from '../resources/theme'; import moment from 'moment'; interface Time { hours: string; minutes: string; } interface State { isDatePickerVisible: boolean; date: Date | null; isTimePickerVisible: boolean; time: Time | null; } interface Props { title: string; time: string; onDateSelected: (date: Date) => void; onTimeSelected: (date: Time) => void; initialDate?: string; initialTime?: string; mode?: 'date' | 'time' | 'datetime' | undefined; dateFormat?: string; edit?: any; haveEnd?: boolean; haveStart?: boolean; } /** * Date picker component based on `react-native-paper-dates` */ class PickDateAndTime extends Component<Props, State> { constructor(props: any) { super(props); const date = props.initialDate !== null ? new Date(props.initialDate) : null; const time = props.initialTime !== null && props.initialTime !== undefined ? { hours: props.initialTime.split(':')[0], minutes: props.initialTime.split(':')[1], } : null; this.state = { isDatePickerVisible: false, date, isTimePickerVisible: false, time, }; } toggleDatePicker = (): void => { this.setState(preState => ({ isDatePickerVisible: !preState.isDatePickerVisible, })); }; toggleTimePicker = (): void => { this.setState(preState => ({ isTimePickerVisible: !preState.isTimePickerVisible, })); }; handleTimePicked = (time: any): void => { const newTime = time ?? new Date().getTime(); this.setState({time: newTime, isTimePickerVisible: false}); this.props.onTimeSelected(newTime); }; handleDatePicked = (date: any): void => { const newDate = date.date ?? new Date(); this.setState({date: newDate, isDatePickerVisible: false}); this.props.onDateSelected(newDate); }; render(): React.ReactElement { const {date, isDatePickerVisible, time, isTimePickerVisible} = this.state; const {dateFormat} = this.props; const displayText = date != null ? dateFormat !== '' ? dayjs(date).format(dateFormat) : date : ''; const displayTime = time != null ? moment(time as any).format('HH:mm') : ''; return ( <PaperProvider theme={{...theme}}> <DatePickerModal locale="en" mode={'single'} label={ this.props.edit === true ? 'Izmenite datum' : 'Izaberite datum' } animationType={'fade'} saveLabel="Potvrdi" visible={isDatePickerVisible} onDismiss={this.toggleDatePicker} date={date ?? new Date()} onConfirm={this.handleDatePicked} startYear={1950} validRange={{ endDate: this.props.haveEnd ? new Date() : undefined, startDate: this.props.haveStart ? new Date() : undefined, }} /> <TimePickerModal visible={isTimePickerVisible} onDismiss={this.toggleTimePicker} onConfirm={this.handleTimePicked} label={ this.props.edit === true ? 'Izmenite vreme' : 'Izaberite vreme' } uppercase={true} cancelLabel="Otkaži" confirmLabel="Potvrdi" animationType="fade" inputFontSize={33} locale="en" /> <NewRow height={10} /> <View style={{ flexDirection: 'row', width: '100%', justifyContent: 'space-between', }}> <View style={{width: '45%', marginLeft: 10}}> {this.props.edit === true ? ( <Button mode={'outlined'} style={[styles.buttonStyle]} labelStyle={styles.labelStyle} onPress={this.toggleDatePicker}> {'Izmeni datum'} </Button> ) : ( <Button mode={'outlined'} style={[styles.buttonStyle]} labelStyle={styles.labelStyle} onPress={this.toggleDatePicker}> {'Dodaj datum'} </Button> )} </View> <View style={{width: '45%', marginRight: 10}}> {this.props.edit === true ? ( <Button mode={'outlined'} style={[styles.buttonStyle]} labelStyle={styles.labelStyle} onPress={this.toggleTimePicker}> {'Izmeni vreme'} </Button> ) : ( <Button mode={'outlined'} style={[styles.buttonStyle]} labelStyle={styles.labelStyle} onPress={this.toggleTimePicker}> {'Dodaj vreme'} </Button> )} </View> </View> <NewRow height={10} /> {displayText !== '' && ( <View style={{flexDirection: 'row', marginLeft: 20}}> <Text style={{ color: colors.blue, fontSize: fontSize.font16, fontWeight: 'normal', }}> {'Datum: '} </Text> <Text style={{ color: colors.blue, fontSize: fontSize.font16, fontWeight: 'normal', }}> {displayText.toString()} </Text> </View> )} {displayTime !== '' && ( <View style={{flexDirection: 'row', marginLeft: 20}}> <Text style={{ color: colors.blue, fontSize: fontSize.font16, fontWeight: 'normal', }}> {'Vreme: '} </Text> <Text style={{ color: colors.blue, fontSize: fontSize.font16, fontWeight: 'normal', }}> {displayTime} </Text> </View> )} </PaperProvider> ); } } const styles = StyleSheet.create({ buttonStyle: { alignSelf: 'center', width: '100%', borderColor: colors.blue, }, labelStyle: { color: colors.blue, fontSize: fontSize.font12, fontWeight: '700', }, }); export default PickDateAndTime;
解决方案
1. 启用组件自带格式化
给DatePickerModal添加format属性指定目标格式,同时设置textInputMode触发适配的日期键盘:
<DatePickerModal // 保留原有属性 format="MM/DD/YYYY" textInputMode="datetime" />
2. 自定义实时格式化逻辑
如果组件自带功能不生效,手动监听输入并插入斜杠:
// 扩展State interface State { // 原有状态 inputDate: string; } // 构造函数初始化 constructor(props: any) { super(props); // 原有代码 this.state = { // 原有状态 inputDate: '', }; } // 格式化输入的工具函数 const formatDateInput = (text: string) => { const cleaned = text.replace(/\D/g, ''); let formatted = ''; if (cleaned.length >= 2) formatted += cleaned.substring(0, 2) + '/'; if (cleaned.length >= 4) formatted += cleaned.substring(2, 4) + '/'; formatted += cleaned.length > 4 ? cleaned.substring(4, 8) : cleaned.substring(2); return formatted; }; // 更新DatePickerModal配置 <DatePickerModal // 保留原有属性 onChangeText={(text) => { const formatted = formatDateInput(text); this.setState({ inputDate: formatted }); // 输入完整时同步日期状态 if (formatted.length === 10) { const [month, day, year] = formatted.split('/'); this.setState({ date: new Date(`${year}-${month}-${day}`) }); } }} value={this.state.inputDate} />
3. 调整键盘类型
将键盘类型改为default,让用户可以手动输入斜杠:
<DatePickerModal // 保留原有属性 keyboardType="default" />
4. 检查版本兼容性
更新到最新版react-native-paper-dates,修复旧版本的格式化bug:
npm update react-native-paper-dates # 或 yarn upgrade react-native-paper-dates
内容的提问来源于stack exchange,提问作者Kristina Dzelebdzic
相关产品推荐
相关产品推荐

