Next.js 13.5.7中DatePicker显示构建时间而非当前日期问题
Next.js 13.5.7 日期组件显示构建时日期的问题
问题详情
部署Next.js 13.5.7项目后,react-datepicker组件固定显示构建时刻的日期(例:2025-02-26),但页面div中渲染的日期能正常显示当前日期(例:2025-02-28)。尝试直接初始化useState、用useEffect设置初始日期均无效,且其他日期组件也存在相同问题。
问题代码
'use client' import React, { useEffect, useState } from 'react'; import DatePicker from 'react-datepicker'; import 'react-datepicker/dist/react-datepicker.css'; export const Test3 = () => { const [selectedDate, setSelectedDate] = useState(null); useEffect(() => { setSelectedDate(new Date()); }, []); const handleSubmit = (event) => { event.preventDefault(); alert(`Selected Date (UTC): ${selectedDate.toUTCString()}\nSelected Date (Locale): ${selectedDate.toLocaleString()}`); }; return ( <form onSubmit={handleSubmit}> <DatePicker selected={selectedDate} onChange={(date) => setSelectedDate(date)} inline /> <button type="submit">Submit</button> <div>selected date: {selectedDate ? selectedDate.toLocaleString() : "not selected"}</div> </form> ); }; export default Test3;
解决方案
核心原因
Next.js App Router默认启用静态渲染,组件会在构建阶段生成静态HTML并缓存。react-datepicker这类依赖客户端DOM的组件,在静态HTML中会保留构建时的日期状态,即便React状态在客户端更新,组件内部的DOM也未同步更新。
修复代码
通过添加客户端就绪状态,强制DatePicker在客户端挂载完成后再渲染,确保使用当前客户端日期:
'use client' import React, { useEffect, useState } from 'react'; import DatePicker from 'react-datepicker'; import 'react-datepicker/dist/react-datepicker.css'; export const Test3 = () => { const [selectedDate, setSelectedDate] = useState(null); const [isClientMounted, setIsClientMounted] = useState(false); useEffect(() => { // 客户端挂载后再设置日期并标记就绪 setSelectedDate(new Date()); setIsClientMounted(true); }, []); const handleSubmit = (event) => { event.preventDefault(); alert(`Selected Date (UTC): ${selectedDate.toUTCString()}\nSelected Date (Locale): ${selectedDate.toLocaleString()}`); }; return ( <form onSubmit={handleSubmit}> {/* 仅在客户端就绪后渲染DatePicker */} {isClientMounted && ( <DatePicker selected={selectedDate} onChange={(date) => setSelectedDate(date)} inline /> )} <button type="submit">Submit</button> <div>selected date: {selectedDate ? selectedDate.toLocaleString() : "not selected"}</div> </form> ); }; export default Test3;
替代方案
如果不想添加额外状态,也可以直接将useState的初始值设为客户端环境下的日期,但需要注意避免构建时执行:
const [selectedDate, setSelectedDate] = useState(() => { // 仅在客户端初始化日期 if (typeof window !== 'undefined') { return new Date(); } return null; });
不过这种方式的可靠性略低,因为Next.js在静态渲染时仍可能执行该初始化函数,推荐优先使用第一种方案。
内容的提问来源于stack exchange,提问作者imsuktoday
相关产品推荐
相关产品推荐

