You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 04:49:59