分享
7.为什么说 Immer.js 在现代 Redux 生态中扮演着如此重要的角色?
输入“/”快速插入内容
7.为什么说 Immer.js 在现代 Redux 生态中扮演着如此重要的角色?
用户8691
用户8691
2025年9月18日修改
为什么说 Immer 是现代 Redux 的灵魂?
在 Redux 的世界里,有一个核心原则不可动摇:**状态(State)是只读的,且唯一修改它的方式是创建并派发(dispatch)一个动作(Action)**。这一设计保证了状态变更的可预测性,也带来了时间旅行调试等强大功能。但长久以来,开发者们在践行这一“不可变性(Immutability)”原则时,却常常陷入繁琐和痛苦的境地。
这正是 Immer.js 出现的意义。它并非要颠覆 Redux,恰恰相反,它是为了让开发者能更优雅、更直观地遵循 Redux 的核心原则。可以说,Immer 是现代 Redux 开发体验的灵魂所在。
Redux 不可变性的“初心”与现实困境
首先,我们回顾一下为什么 Redux 如此强调不可变性。
1.
变更可追溯
:每次状态变更都产生一个全新的状态对象,我们可以清晰地追踪每一次变化,这对于调试,尤其是“时间旅行”,至关重要。
2.
性能优化
:在 React 这类视图库中,判断组件是否需要重新渲染,最高效的方式就是进行一次浅比较(shallow comparison)。如果 state 的引用地址没有变,就意味着它没有更新,其关联的组件也无需重新渲染。
这些优点是 Redux 架构的基石。然而,在实践中,遵循不可变性往往意味着大量的样板代码。
想象一个常见的场景:我们需要更新一个深层嵌套对象中的某个属性。比如,在一个用户设置中,更新主题颜色。
我们的 State 结构可能如下:
代码块
JavaScript
const state = {
user: {
id: 1,
profile: {
name: '张三',
settings: {
theme: 'light',
notifications: true,
},
},
},
// ... 其他 state
};
为了在
reducer
中将
theme
从
'light'
修改为
'dark'
,同时保持不可变性,我们需要手动复制每一层路径上的对象:
代码块
JavaScript
// Before Immer.js
const nextState = {
...state, // 1. 复制顶层 state
user: {
...state.user, // 2. 复制 user 对象
profile: {
...state.user.profile, // 3. 复制 profile 对象
settings: {
...state.user.profile.settings, // 4. 复制 settings 对象
theme: 'dark', // 5. 最后,应用我们的修改
},
},
},
};