react 不可变数据更新(Immutable Update)合并对象 类似与Java 的BeanUtils.copyProperties‌

js 复制代码
{ 
  ...state,                       // 保留原有的 state 的其他部分
  data: { 
    ...state.data,                // 保留 state.data 中的其他字段
    ...action.payload             // 使用 action.payload 覆盖 state.data 中需要更新的字段
  }
}

这段代码是 Redux 中常见的一种状态更新方式,用于不可变数据更新(Immutable Update)。

它的作用是通过合并对象的方法,更新嵌套状态中的某些字段,同时保持其他字段不变。

作用:

...state:

保留当前状态对象的所有属性。

...state.data:

保留 state.data 对象的所有属性。

...action.payload:

用 action.payload 中的属性更新(或添加到) state.data 对象。

示例 1:Redux 状态更新

假设 Redux 状态如下:

js 复制代码
const initialState = {
  data: {
    name: "Alice",
    age: 25,
    location: "New York"
  },
  isLoading: false,
};

如果 action.payload 是:

js 复制代码
{ age: 26, location: "Los Angeles" }

Reducer 中使用这段代码:

js 复制代码
function reducer(state = initialState, action) {
  switch (action.type) {
    case "UPDATE_USER":
      return { 
        ...state, 
        data: { 
          ...state.data, 
          ...action.payload 
        } 
      };
    default:
      return state;
  }
}

结果:

js 复制代码
{
  data: {
    name: "Alice",
    age: 26,
    location: "Los Angeles"
  },
  isLoading: false
}

示例 2:仅更新部分嵌套字段

如果只需要更新嵌套字段的一部分,比如 data.location,你可以像这样构造 action.payload:

js 复制代码
dispatch({
  type: "UPDATE_USER",
  payload: { location: "San Francisco" },
});

Reducer 会合并更新 data 中的 location 字段,其余字段保持不变。

结果:

js 复制代码
{
  data: {
    name: "Alice",
    age: 25,
    location: "San Francisco"
  },
  isLoading: false
}

为什么这样写?

Redux 状态管理要求 状态是不可变的(Immutable),即不能直接修改现有状态,而需要返回一个新的状态对象。这 种写法利用对象解构(spread syntax)来实现:

创建一个包含旧状态的浅拷贝(...state)。

更新状态中嵌套的某些字段(通过 ...state.data 和 ...action.payload 合并)。

返回一个全新的状态对象。

注意事项

深层嵌套结构: 如果状态嵌套层级较深,这种方法可能变得冗长。可以考虑使用工具库如 immer 简化嵌套状态的更新。

js 复制代码
import produce from "immer";

const newState = produce(state, draft => {
  draft.data.age = 26;
  draft.data.location = "Los Angeles";
});

覆盖与合并:

如果 action.payload 中的字段与 state.data 中的字段重名,则会覆盖。

如果 action.payload 包含新字段,则会添加到 state.data 中。

性能:

解构操作创建了浅拷贝,对于大对象或深层结构可能会带来性能开销。

如果性能是关键问题,需谨慎处理状态更新。

总结

这段代码是 Redux 中的一种标准做法,用于更新嵌套的状态数据,同时确保状态的不可变性。这种方式简单且直观,但在深层嵌套状态场景中需要额外的工具支持(如 Immer)以提升可维护性和可读性。

相关推荐
剪刀石头布啊6 分钟前
泛洪DFS、BFS
前端
qetfw6 分钟前
Windows Server AD CS:根 CA、Web 证书模板与域内自动注册
前端·windows·windows-server
剪刀石头布啊6 分钟前
为什么React组件很少前缀,而vue的不少组件都有前缀
前端
剪刀石头布啊12 分钟前
gird网格布局
前端
不会写DN13 分钟前
Go日志库工程选型与逃逸分析评测报告
java·服务器·golang
啃火龙果的兔子13 分钟前
Google Chrome(谷歌浏览器)常用快捷键
前端·chrome
剪刀石头布啊16 分钟前
js真的是单线程实现异步并发么?
前端
剪刀石头布啊21 分钟前
js中改变this指向的操作有哪些
前端
剪刀石头布啊21 分钟前
vue、react 列表中使用 index 作为 key 的话,修改某一个元素后会发生什么
前端
方方洛22 分钟前
glowglow:语言无关的语法高亮器是怎么实现的
前端·前端框架