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

Redux Toolkit日期对象序列化报错及解决方案咨询

问题:Redux状态中非序列化日期对象的处理方案

错误信息

A non-serializable value was detected in the state, in the path: `generate.createdImage.createdAt`. Value: Mon Jan 15 2024 17:10:56 GMT+0000 (Greenwich Mean Time) 

相关reducer:generate/addGeneratedImage

问题背景

表单提交后在数据库创建包含createdAt日期对象的Post,返回前端后存入Redux状态,触发上述错误。

核心疑问

  1. 是否应在MongoDB中将日期存储为字符串?若是,如何在服务端查询此类字符串(例如获取最新5条帖子)?
  2. 若继续使用日期对象,应在何处进行序列化?是否在返回前端之前?

解决方案

1. MongoDB日期存储方式选择

不推荐将日期存储为字符串。MongoDB原生支持Date类型,存储日期对象有以下优势:

  • 原生支持日期相关查询操作(排序、范围筛选等),性能远高于字符串类型
  • 避免字符串格式不一致导致的查询错误
  • 占用存储空间更小

如果非要存储为字符串,必须统一使用ISO 8601格式(如2024-01-15T17:10:56.000Z),查询最新5条时可直接按字符串排序:

// 服务端查询示例(字符串日期)
const latestPosts = await db.post.findMany({
  take: 5,
  orderBy: { createdAt: 'desc' }
});

但这种方式的查询效率和可靠性都不如原生Date类型,因此优先选择存储Date对象。

2. 日期对象的序列化时机

必须在服务端返回前端之前完成序列化,将Date对象转换为可序列化的字符串(推荐ISO格式)。Redux要求状态必须是纯可序列化类型(plain object、数组、字符串、数字等),Date对象不属于此类,因此需要提前转换。

修改服务端createPostPartial函数,在返回结果时处理createdAt:

export const createPostPartial = async (imageObject: ImagePartialProps) => {
  const { userId, s3FileURL, imageParams, revisedPrompt } = imageObject;

  let post;

  try {
    post = await db.post.create({
      data: {
        imageUrl: s3FileURL,
        size: imageParams.size!,
        hd: imageParams.quality === 'hd' ? true : false,
        prompt: imageParams.prompt,
        revisedPrompt: revisedPrompt,
        model: imageParams.model!,
        authorId: userId,
      },
    });
  } catch (error) {
    return {
      error: 'Failed to create the post',
    };
  }

  // 将Date对象转为ISO格式字符串,确保可序列化
  return {
    ...post,
    createdAt: post.createdAt.toISOString()
  };
};

前端ImagePostProps类型中createdAt已定义为string,与转换后的数据类型匹配,无需修改前端代码。后续若需要在前端使用日期对象,可通过new Date(post.createdAt)转回。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 02:06:07