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

React中使用JSON.stringify处理errors对象出现循环值错误的原因及解决

React Hook Form中JSON.stringify循环引用错误问题解析

问题场景

我在React应用中使用React Hook Form编写了如下组件代码:

import * as React from "react";
import * as ReactDOM from "react-dom";
import { useForm } from "react-hook-form";

import "./styles.css";

const App = () => {
  const {
    register,
    handleSubmit,
    setValue,
    formState: { errors }
  } = useForm({
    defaultValues: {
      firstName: "",
      lastName: "luo",
      amount: ""
    }
  });

  const onSubmit = (data) => {
    // alert(JSON.stringify(data));
  };

  console.log(JSON.stringify(errors), "f");

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <label>First Name</label>
      <input type="text" {...register("firstName", { required: true })} />
      <input type="submit" />
    </form>
  );
};

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

点击提交按钮时,触发了Uncaught TypeError: cyclic object value错误,该错误由JSON.stringify()调用引发。需要解决两个问题:

  1. 为什么会出现这个错误?
  2. 如何正确使用JSON.stringify()解决该问题?

错误原因

React Hook Form返回的errors对象内部存在循环引用关系——对象的某个属性引用了对象本身,或者不同属性之间互相引用。当JSON.stringify()尝试序列化这类对象时,会陷入无限递归遍历,最终抛出循环引用的错误。

你代码中直接对errors执行JSON.stringify(errors),而这个errors并非普通的扁平对象,它包含了React Hook Form内部用于追踪表单状态的关联引用,导致序列化失败。


解决方法

针对React Hook Form的errors对象,有两种可靠的处理方式:

方式1:提取核心属性后序列化

如果只需要错误信息中的核心内容(比如错误消息、字段类型),可以手动提取这些属性后再序列化:

// 提取errors中的字段错误核心信息
const serializedErrors = JSON.stringify(
  Object.fromEntries(
    Object.entries(errors).map(([field, err]) => [
      field, { message: err.message, type: err.type }
    ])
  )
);
console.log(serializedErrors, "f");

方式2:自定义序列化函数处理循环引用

如果需要保留更多errors对象的内容,可以给JSON.stringify()传入自定义的replacer函数,跳过循环引用的属性:

const getCircularReplacer = () => {
  const seen = new WeakSet();
  return (key, value) => {
    if (typeof value === "object" && value !== null) {
      if (seen.has(value)) {
        return; // 跳过已遍历过的循环引用对象
      }
      seen.add(value);
    }
    return value;
  };
};

// 使用自定义replacer序列化errors
console.log(JSON.stringify(errors, getCircularReplacer()), "f");

调试替代方案

如果只是为了调试查看errors内容,完全不需要用JSON.stringify()——直接在控制台打印errors对象即可:

console.log(errors, "f");

浏览器控制台会自动处理循环引用,展开后可以正常查看对象的所有属性。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 22:30:54