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

React Hooks中handleEvent函数内无法获取DateRangePicker更新后state如何解决

问题原因

React 的 useState 更新属于异步批量操作,在事件回调函数中调用 setFromDate、setToDate 之后,当前函数作用域内的 fromDate、toDate 仍属于本次渲染闭包缓存的旧值,不会立刻同步更新,因此你在函数内部读取到的永远是上一次的选中结果。

解决方案

你可以直接使用事件回调返回的最新日期值构造请求,不需要依赖 state 更新后的结果,调整后的代码如下:

import React, { useState } from "react";
import DateRangePicker from "react-bootstrap-daterangepicker";
import "bootstrap-daterangepicker/daterangepicker.css";
import moment from "moment";
import DataProvider from "context/DataContext";

import ApiService from "services/api";

export default function DatePicker() {
  const [fromDate, setFromDate] = useState(new Date());
  const [toDate, setToDate] = useState(new Date());

  const range = {
    Today: [moment(), moment()],
    Yesterday: [moment().subtract(1, "days"), moment().subtract(1, "days")],
    "Last 7 Days": [moment().subtract(6, "days"), moment()],
    "Last 30 Days": [moment().subtract(29, "days"), moment()],
    "This Month": [moment().startOf("month"), moment().endOf("month")],
    "Last Month": [
      moment().subtract(1, "month").startOf("month"),
      moment().subtract(1, "month").endOf("month"),
    ],
    "Last Year": [
      moment().subtract(1, "year").startOf("year"),
      moment().subtract(1, "year").endOf("year"),
    ],
  };

  const handleEvent = (event, picker) => {
    const newStart = picker.startDate._d;
    const newEnd = picker.endDate._d;
    // 更新state用于页面显示
    setFromDate(newStart);
    setToDate(newEnd);
   
    // 直接用最新的日期构造请求
    const requestData = {
      metrics: ["views"],
      project_id: "abc",
      date_range: { start_at: newStart, end_at: newEnd },
    };

    ApiService.create({ requestData }).then((onSuccess) => {
      console.log(onSuccess);
    });
  };

  return (
    <DateRangePicker
      ranges={range}
      alwaysShowCalendars={false}
      onEvent={handleEvent}
    >
      <button>
        {moment(fromDate).format("ll")} to {moment(toDate).format("ll")}
      </button>
    </DateRangePicker>
  );
}
可选方案

如果你有其他逻辑必须依赖更新后的 state 执行,可以用 useEffect 监听日期变化触发请求:

// 组件内新增useEffect
useEffect(() => {
  const requestData = {
    metrics: ["views"],
    project_id: "abc",
    date_range: { start_at: fromDate, end_at: toDate },
  };
  ApiService.create({ requestData }).then((onSuccess) => {
    console.log(onSuccess);
  });
}, [fromDate, toDate])

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 17:12:02