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

React中如何提取对象变更字段供PATCH请求使用,有哪些实现方法或库?

解决方案

前置注意事项

你的示例代码存在两处需要修正的问题:

  1. let dynamicObject = obj 属于对象引用赋值,两个变量指向同一块内存地址,修改obj的属性等同于修改dynamicObject。如果要保留原始对象用于对比,需要先对初始对象做拷贝:
    // 单层对象用浅拷贝即可
    let originalObj = {...obj};
    // 多层嵌套对象可用深拷贝,也可以用lodash的cloneDeep方法
    // let originalObj = JSON.parse(JSON.stringify(obj));
    
  2. 示例里的createdBy = 'ken'属于全局变量赋值,正确写法应为obj.createdBy = 'ken',否则不会修改到对象的对应属性。

现成库方案

Lodash 实现(最常用)

绝大多数前端项目都已引入Lodash,直接用内置方法组合即可实现需求,同时支持深浅对比,兼容单层/嵌套复杂对象的场景:

import _ from 'lodash';

function getChangedFields(original, updated) {
  return _.pickBy(updated, (value, key) => !_.isEqual(value, original[key]));
}

通用手动实现方案

如果不想引入第三方依赖,可以根据业务场景选择对应实现:

浅比较版本(适用于单层对象、字段值都是基础类型的场景)

即你示例中的使用场景,实现逻辑简单性能高:

function getChangedFields(original, updated) {
  const changed = {};
  for (const key in updated) {
    // hasOwnProperty判断用于过滤掉原型链上的属性,不需要可删除
    if (updated.hasOwnProperty(key) && original.hasOwnProperty(key) && updated[key] !== original[key]) {
      changed[key] = updated[key];
    }
  }
  return changed;
}

深比较版本(适用于包含嵌套对象、数组的复杂对象场景)

function deepEqual(a, b) {
  if (a === b) return true;
  if (typeof a !== 'object' || a === null || typeof b !== 'object' || b === null) return false;
  
  const keysA = Object.keys(a), keysB = Object.keys(b);
  if (keysA.length !== keysB.length) return false;
  
  for (const key of keysA) {
    if (!keysB.includes(key) || !deepEqual(a[key], b[key])) return false;
  }
  return true;
}

function getChangedFieldsDeep(original, updated) {
  const changed = {};
  for (const key in updated) {
    if (updated.hasOwnProperty(key) && original.hasOwnProperty(key) && !deepEqual(updated[key], original[key])) {
      changed[key] = updated[key];
    }
  }
  return changed;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 19:39:04