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

使用React Day Picker与Next.js无法设置初始选中日期

问题解决思路

问题根源

刷新页面时,React Query的异步请求还未返回数据,组件初始化阶段initialDatesTest是undefined,导致useState的初始值为空数组。等请求完成拿到数据后,useState不会自动更新状态,所以选中日期无法显示;而站点内跳转时React Query存在缓存,初始化就能拿到数据,因此显示正常。

解决方案1:用useEffect同步React Query数据到本地state

监听initialDatesTest的变化,当数据加载完成后更新本地days状态:

const {
  data: initialDatesTest,
  error,
  isLoading,
} = useQuery({
  queryKey: ["dates"],
  queryFn: getDates,
});

async function getDates() {
  const response = await fetch("/api/dates-to-exclude");
  const data = await response.json();
  const parsedExcludedDates = data.excludedDates.PartyExcludeDates.map(
    (dateString: string) => new Date(dateString)
  );

  return parsedExcludedDates;
}

const [days, setDays] = useState<Date[] | undefined>([]);

// 监听React Query数据变化,同步到本地state
useEffect(() => {
  if (initialDatesTest) {
    setDays(initialDatesTest);
  }
}, [initialDatesTest]);

// 渲染部分保留
<Controller
  control={control}
  name="DayPicker"
  render={({ field }) => (
    <DayPicker
      mode="multiple"
      min={1}
      selected={days}
      onSelect={setDays}
      footer={footer}
      disabled={{ before: new Date() }}
      numberOfMonths={1}
    />
  )}
/>

解决方案2:结合缓存数据与本地交互(更优)

如果用户需要手动修改选中日期,可通过useRef标记初始化状态,避免后续数据更新覆盖用户手动修改的内容:

const {
  data: initialDatesTest,
  error,
  isLoading,
} = useQuery({
  queryKey: ["dates"],
  queryFn: getDates,
});

async function getDates() {
  const response = await fetch("/api/dates-to-exclude");
  const data = await response.json();
  const parsedExcludedDates = data.excludedDates.PartyExcludeDates.map(
    (dateString: string) => new Date(dateString)
  );

  return parsedExcludedDates;
}

// 标记是否已经完成初始状态赋值
const hasInitialized = useRef(false);
const [days, setDays] = useState<Date[] | undefined>([]);

useEffect(() => {
  if (initialDatesTest && !hasInitialized.current) {
    setDays(initialDatesTest);
    hasInitialized.current = true;
  }
}, [initialDatesTest]);

// 渲染部分保留
<Controller
  control={control}
  name="DayPicker"
  render={({ field }) => (
    <DayPicker
      mode="multiple"
      min={1}
      selected={days}
      onSelect={setDays}
      footer={footer}
      disabled={{ before: new Date() }}
      numberOfMonths={1}
    />
  )}
/>

额外提示

如果不需要用户修改选中日期,甚至可以直接用initialDatesTest作为DayPicker的selected值,省去本地state:

<DayPicker
  mode="multiple"
  min={1}
  selected={initialDatesTest || []}
  footer={footer}
  disabled={{ before: new Date() }}
  numberOfMonths={1}
/>

内容的提问来源于stack exchange,提问作者user10980228

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 09:40:12