react-datepicker触发setState无法保留dd/MM/yy自定义显示格式问题
问题原因
react-datepicker的dateFormat属性仅控制组件输入框内的展示格式,onChange回调默认返回的始终是原生Date类型对象,不会自动帮你转成格式化后的字符串。
解决方案
方案1:状态直接存储格式化后的字符串
如果你的业务场景里不需要频繁对日期做计算、排序等操作,只需要存储展示用的字符串,可以按照如下修改代码:
import DatePicker from "react-datepicker"; import "react-datepicker/dist/react-datepicker.css"; import { useState } from "react"; // 格式化Date为dd/MM/yy字符串的工具函数 const formatDateToStr = (date) => { if(!date) return '' const day = String(date.getDate()).padStart(2, '0') const month = String(date.getMonth() + 1).padStart(2, '0') const year = String(date.getFullYear()).slice(-2) return `${day}/${month}/${year}` } // 字符串转回Date对象的工具函数 const parseStrToDate = (str) => { if(!str) return new Date() const [day, month, year] = str.split('/') return new Date(+`20${year}`, +month - 1, +day) } export default function Bodyweight() { // 初始化时就转成字符串存储 const [startDate, setStartDate] = useState(formatDateToStr(new Date())); return( <div> <DatePicker dateFormat="dd/MM/yy" selected={parseStrToDate(startDate)} onChange={(date) => setStartDate(formatDateToStr(date))} /> </div> )}
方案2:状态仍存储Date对象,使用时再格式化
如果你的业务后续需要对日期做计算、范围校验等操作,更推荐保留Date类型的状态,只在需要展示、提交接口的时候再转成目标格式的字符串,这样可以避免多次转义出现的格式错误:
import DatePicker from "react-datepicker"; import "react-datepicker/dist/react-datepicker.css"; import { useState } from "react"; const formatDateToStr = (date) => { if(!date) return '' const day = String(date.getDate()).padStart(2, '0') const month = String(date.getMonth() + 1).padStart(2, '0') const year = String(date.getFullYear()).slice(-2) return `${day}/${month}/${year}` } export default function Bodyweight() { const [startDate, setStartDate] = useState(new Date()); // 示例:提交接口时使用格式化后的字符串 const handleSubmit = () => { const submitDate = formatDateToStr(startDate) // 后续接口提交逻辑 console.log('要提交的日期格式:', submitDate) } return( <div> <DatePicker dateFormat="dd/MM/yy" selected={startDate} onChange={(date) => setStartDate(date)} /> <button onClick={handleSubmit}>提交</button> </div> )}
注意事项
- 如果项目本身已经引入了
date-fns、dayjs等日期处理库,可以直接用库提供的格式化方法,不用自己写工具函数,比如dayjs的写法是dayjs(date).format('DD/MM/YY') - 自行实现工具函数时要注意,原生Date对象的月份是从0开始计数的,不要忘记加1;年份取后两位的时候要补全前缀避免边界年份的解析错误。
内容的提问来源于stack exchange,提问作者AlexJanow
相关产品推荐
相关产品推荐

