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

React组件中new Date()引发无限重渲染,转字符串正常的原因解析

React Formik日期字段无限重渲染问题解析

问题背景

用户提供的React组件代码如下:

import { useFormik } from 'formik';
import React from 'react';

const MyForm = () => {
  const initialValues = {
    date: new Date().toISOString().slice(0, 10), // 获取YYYY-MM-DD格式的当前日期
    // 其他表单字段...
  };

  const onSubmit = (values) => {
    // 处理表单提交
    console.log(values);
  };

  const formik = useFormik({
    initialValues,
    onSubmit,
  });

  return (
    <form onSubmit={formik.handleSubmit}>
      <div>
        <label htmlFor="date">Date:</label>
        <input
          type="date"
          id="date"
          name="date"
          onChange={formik.handleChange}
          value={formik.values.date}
        />
      </div>
      {/* 其他表单字段... */}
      <button type="submit">Submit</button>
    </form>
  );
};

export default MyForm;

疑问

为何当将date设为new Date()时,组件会发生无限重渲染;而设为new Date().toISOString().slice(0, 10)时却能正常工作?背后的原因是什么?

核心原因

  • new Date()是引用类型:每次组件渲染时,new Date()都会生成一个全新的Date对象。Formik内部会对传入的initialValues做浅比较,发现每次的date都是不同的对象引用,就会判定表单状态需要更新,触发表单逻辑重新计算,进而导致组件重渲染。而重渲染又会再次创建新的Date对象,形成无限循环。
  • new Date().toISOString().slice(0, 10)是原始值类型(字符串):这个表达式返回的是YYYY-MM-DD格式的字符串,属于原始值。只要当前日期不变,每次渲染生成的字符串内容完全一致。Formik比较时会认为initialValues没有变化,不会触发不必要的状态更新,组件也就不会出现无限重渲染的问题。

哪怕日期发生变化,字符串的比较是值比较,只有内容真的改变时才会触发更新,不会像Date对象那样因为每次都是新引用而被误判为状态变化。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 04:40:10