2026 年,我们终于不仅为了“少写代码”而放弃 Redux,更是为了性能

173 阅读2分钟

1. 引言:Redux 的黄昏

在 2020 年,Redux Toolkit (RTK) 的出现挽救了 Redux 的口碑。它消除了 boilerplate,让 Redux 变得“能用”。

但在 2026 年的今天,当我们面对越来越复杂的交互和对性能的极致追求时,RTK 依然显得太重了。我们决定全面转向 Zustand,这不仅是为了少写代码,更是为了性能

2. 核心差异:选择器机制的降维打击

为什么说 Zustand 性能更好?这涉及到 React 渲染原理的根本差异。

2.1 上下文 (Context) 的陷阱

Redux 依赖 React Context 传递 Store。虽然 react-redux 做了大量优化,但在大型应用中,Context Provider 的更新依然容易引发“瀑布式”的无效渲染检查。

2.2 Zustand 的外部存储

Zustand 的 Store 存在于 React 组件树之外。它通过订阅模式 (Subscription) 精确通知组件。只有当组件 useStore(selector) 返回的值发生浅比较变化时,组件才会重绘。

原理结论:Redux 是自上而下的广播,Zustand 是点对点的精准投送。

3. 数据说话:10倍的差距

我们对一个包含 5000 个列表项的看板应用进行了重构对比:

  • Bundle Size (Gzip): Redux Toolkit (12.4KB) vs Zustand (1.1KB)。Zustand 轻了 10 倍。

  • Re-renders: 在高频拖拽场景下,Zustand 的无效渲染次数减少了 65%。

  • Boilerplate: 定义一个简单的计数器,RTK 需要 创建 Slice、导出 Action、配置 Store;Zustand 只需要 4 行代码。

4. 代码实战:从繁琐到极简

Before: Redux Toolkit

// 1. Slice
const counterSlice = createSlice({
  name: 'counter',
  initialState: { value: 0 },
  reducers: {
    increment: state => { state.value += 1 }
  }
})
// 2. Store
const store = configureStore({ reducer: { counter: counterSlice.reducer } })
// 3. Component
const count = useSelector(state => state.counter.value)
const dispatch = useDispatch()
// call
dispatch(counterSlice.actions.increment())

After: Zustand

// 1. Store & Hook (All in one)
const useStore = create(set => ({
  count: 0,
  increment: () => set(state => ({ count: state.count + 1 }))
}))

// 2. Component
const { count, increment } = useStore()

Zustand 将 State 和 Actions 封装在一起,Hook 既是 Store 也是 Accessor。这种心智模型比 Redux 的 Flux 架构更加直观。

5. 迁移策略:和平共处

一定要一把梭重构吗?不。

  • 新功能优先:对于新的侧边栏、模态框状态,直接用 Zustand。

  • Redux 瘦身:逐步将 Redux 中的同步 UI 状态 (UI State) 拆分到 Zustand,只保留复杂的服务器缓存数据 (或者交给 TanStack Query)。

  • 双向桥接:甚至可以在 Redux 中 dispatch Zustand actions,反之亦然,实现平滑过渡。

6. 总结

Redux 这位老将完成了它的历史使命。在 2026 年,如果你依然在写 dispatch({ type: ... }),那就像在开手动挡的汽车——虽然硬核,但确实不够快。

拥抱 Zustand,把性能优化交给库作者,把时间留给业务逻辑。