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

React中如何在视图层正确使用更新后的日期状态值?

React日期状态渲染错误解决方案

问题说明

开发React项目时,需实现两处日期展示:

  • span元素:选中日期后替换“Select calendar”文本
  • h2标签:显示选中日期

渲染时出现两个错误:

  1. 使用{appointmentDate.toLocaleDateString()}时,报错Cannot read properties of undefined (reading 'toLocaleDateString')
  2. 直接使用{appointmentDate}时,报错Objects are not valid as a React child (found: [object Date])

原代码:

import { useRef, useState } from "react";
import { Calendar } from "react-date-range";
import { addDays } from "date-fns";
import { format } from "date-fns";
import "react-date-range/dist/styles.css"; // main css file
import "react-date-range/dist/theme/default.css"; // theme css file

export default function App() {
  const [appointmentDate, setAppointmentDate] = useState(new Date());

  const handleDate = (e) => {
    const clickedDate = e.target.value;
    setAppointmentDate(clickedDate);
    document.getElementById("select-calendar").innerHTML =
      appointmentDate.toLocaleDateString();
    console.log(appointmentDate);
  };
  return (
    <div className="App">
      <span id="select-calendar">Select calendar</span>
      <div onClick={handleDate}>
        <Calendar
          onChange={(item) => setAppointmentDate(item)}
          date={appointmentDate}
          className="stay-date"
          name="appointmentDate"
        />
      </div>
      <h2>{appointmentDate.toLocaleDateString()}</h2>
    </div>
  );
}

错误原因

  1. 状态更新异步+事件取值错误:handleDate中尝试读取刚更新的appointmentDate(React状态更新是异步的,此时值未更新),且点击日历非输入元素时e.target.value为undefined,导致状态被设为undefined,后续调用toLocaleDateString报错。
  2. 直接渲染Date对象:React无法直接渲染Date类型对象,必须转为字符串。
  3. 手动操作DOM:使用document.getElementById修改DOM不符合React状态驱动的设计理念,容易导致视图与状态不一致。

解决方案

修改后的代码如下:

import { useState } from "react";
import { Calendar } from "react-date-range";
import "react-date-range/dist/styles.css";
import "react-date-range/dist/theme/default.css";

export default function App() {
  const [appointmentDate, setAppointmentDate] = useState(new Date());

  // 直接利用Calendar组件的onChange回调接收选中的日期
  const handleDateChange = (selectedDate) => {
    setAppointmentDate(selectedDate);
  };

  // 统一格式化日期为字符串
  const formattedDate = appointmentDate.toLocaleDateString();

  return (
    <div className="App">
      {/* 用状态控制span文本,无需手动操作DOM */}
      <span>{formattedDate}</span>
      <Calendar
        onChange={handleDateChange}
        date={appointmentDate}
        className="stay-date"
      />
      <h2>{formattedDate}</h2>
    </div>
  );
}

关键修改点

  • 移除外层div的onClick事件,直接使用Calendar组件自带的onChange回调,该回调会直接返回选中的Date对象,避免了从事件对象取值的错误。
  • 去掉手动操作DOM的代码,通过状态formattedDate控制span的文本,让React自动同步视图与状态。
  • 提前将Date对象格式化为字符串,确保渲染的是React支持的字符串类型,解决“Objects are not valid as a React child”错误。
  • 状态更新后,React自动触发组件重渲染,两处视图会同步显示最新的格式化日期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 18:57:51