React Native中使用Yup与Formik验证DateTimePickerModal的实现方案
问题根因
你当前的实现里维护了两份独立的状态:Formik管理的表单状态、你自己用useState声明的date局部状态。选择日期后你只更新了局部状态,没有同步到Formik的表单字段Arrival_Date中,同时日期输入框的value绑定的是你计算出来的newDate而不是Formik管理的字段值,导致Formik感知不到日期的变化,自然不会触发校验。
修复方案
- 首先移除冗余的局部
date状态,所有表单相关状态统一交给Formik管理 - 选择日期后直接调用Formik提供的
setFieldValue方法更新Arrival_Date字段,同时完成日期格式化 - 将日期输入框的value绑定为Formik管理的
values.Arrival_Date - 优化日期格式化逻辑,避免不稳定的JSON序列化拆分操作
- 删除重复的日期错误提示代码
核心修改代码示例:
// 移除局部的const [date, setDate] = useState(''); const handleConfirm = (selectedDate) => { hideDatePicker(); // 格式化日期:直接用toISOString拆分,比JSON序列化拆分更稳定 const formattedDate = selectedDate.toISOString().split('T')[0]; // 同步更新到Formik的Arrival_Date字段,第三个参数传true表示更新后立即触发校验 setFieldValue('Arrival_Date', formattedDate, true); // 主动标记字段为已触碰,触发错误提示逻辑 setFieldTouched('Arrival_Date', true, true); }; // 移除getDate函数和newDate变量 // 日期输入框修改为: <TextInput onChangeText={handleChange('Arrival_Date')} onBlur={handleBlur('Arrival_Date')} // value绑定Formik管理的字段值 value={Arrival_Date} onFocus={showDatePicker} placeholder="yyyy/mm/dd" placeholderTextColor={COLORS.placeholder_fonts} selectionColor={COLORS.drawer_button} style={styles.textInput} /> // 记得删除重复的那一段日期错误提示代码,你当前写了两次相同的错误判断
优化建议
- 可以在yup校验规则里新增日期格式校验,避免用户手动输入非法格式的日期:
Arrival_Date: yup.string() .required('Please Choose a date') .matches(/^\d{4}-\d{2}-\d{2}$/, '请输入正确的日期格式,如2024-05-20'), - 将
DateTimePickerModal组件移到TouchableOpacity组件外,不要嵌套在可点击组件内部,避免不必要的重复渲染 - 如果需要自定义日期格式,推荐使用
date-fns或dayjs这类轻量日期库处理,比手动拆分字符串兼容性更高
内容的提问来源于stack exchange,提问作者roshan kurikkal
相关产品推荐
相关产品推荐

