目录
  • 什么是状态管理?
  • React 状态管理方案
    • 方案介绍
    • 方案对比
    • Source
    • 相关建议

什么是状态管理?

“状态”是描述应用程序当前行为的任何数据。这可能包括诸如“从服务器获取的对象列表”、“当前选择的项目”、“当前登录用户的名称”和“此模式是否打开?”等值。

众所周知,我们在研发一个复杂应用的过程中,一套好的状态管理方案是必不可少的,既能提升研发效率,又能降低研发维护成本,那么状态管理方案那么多,它们有什么不同,我们又该如何选择适合当前应用的方案呢?

本期将主要就 react 的常用状态管理方案进行对比分析,希望对各位看客有帮助。

React 状态管理方案

方案介绍

  • hook context
  • react-redux
  • mobx
  • zustand
  • jotai
  • valtio

方案对比

框架 原理 优点 缺点
hooks context 基于 react hook,开发者可实现内/外部存储 1. 使用简单
2. 不需要引用第三方库,体积最小
3. 支持存储全局状态,但在复杂应用中不推荐
4. 不依赖 react 上下文,可在组件外调用(外部存储的条件下)
1. context value发生变化时,所有用到这个context的组件都会被重新渲染,基于 content 维护的模块越多,影响范围越大。
2. 使用依赖 provider,修改 store 无法在应用最顶层(App.tsx 层级)触发渲染
3. 受ui框架约束(react)
4. 依赖hooks调用
react-redux Flux思想,发布订阅模式,遵从函数式编程,外部存储 1. 不依赖 react 上下文,可在组件外调用
2. 支持存储全局状态
3.不受ui框架约束
1. 心智模型需要一些时间来理解,特别是当你不熟悉函数式编程的时候
2. 编码繁琐
mobx 观察者模式 + 数据截止,外部存储 1. 使用简单
2. 不依赖 react 上下文,可在组件外调用
3. 支持存储全局状态
4.不受ui框架约束
1.可变状态模型,某些情况下可能影响调试 2. 除了体积相对较大之外,笔者目前未感觉到较为明显的缺点,3.99M
zustand Flux思想,观察者模式,外部存储 1. 轻量,使用简单
2. 不依赖 react 上下文,可在组件外调用
3. 支持存储全局状态
1.框架本身不支持 computed 属性,但可基于 middleware 机制通过少量代码间接实现 computed ,或基于第三方库 zustand-computed 实现
2.受ui框架约束(react / vue)
jotai 基于 react hook,内部存储 1. 使用简单
2. 组件颗粒度较细的情况下,jotai性能更好
3.支持存储全局状态,但在复杂应用中不推荐
1. 依赖 react 上下文, 无法组件外调用,相对而言, zustand 在 react 环境外及全局可以更好地工作
2. 受ui框架约束(react)
valtio 基于数据劫持,外部存储 1. 使用简单,类mobx(类vue)的编程体验
2.支持存储全局状态
3.不依赖 react 上下文,可在组件外调用
4. 不受ui框架约束
1.可变状态模型,某些情况下可能影响调试
2.目前笔者没发现其它特别大的缺点,个人猜测之所以star相对zustand较少,是因为 valtio 的数据双向绑定思想与 react 存在冲突。

Source

  • hooks context

1.使用 react hooks + context 进行方便快捷的状态管理

2.使用 react hooks + context 构建 redux 进行状态管理

react-redux

  • mobx
import React from "react"
import ReactDOM from "react-dom"
import { makeAutoObservable } from "mobx"
import { observer } from "mobx-react"
// 状态及相关事件
class Timer {
    secondsPassed = 0
    constructor() {
        makeAutoObservable(this)
    }
    increase() {
        this.secondsPassed += 1
    }
    reset() {
        this.secondsPassed = 0
    }
}
const myTimer = new Timer()
// 构建可观擦组件
const TimerView = observer(({ timer }) => (
    <button onClick={() => timer.reset()}>Seconds passed: {timer.secondsPassed}</button>
))
ReactDOM.render(<TimerView timer={myTimer} />, document.body)
// 触发更新事件
setInterval(() => {
    myTimer.increase()
}, 1000)
  • zustand
import { create } from 'zustand'
// 状态及相关事件
const useBearStore = create((set) => ({
  bears: 0,
  increasePopulation: () => set((state) => ({ bears: state.bears + 1 })),
  removeAllBears: () => set({ bears: 0 }),
}))
// 渲染视图
function BearCounter() {
  const bears = useBearStore((state) => state.bears)
  return <h1>{bears} around here ...</h1>
}
// 触发更新事件
function Controls() {
  const increasePopulation = useBearStore((state) => state.increasePopulation)
  return <button onClick={increasePopulation}>one up</button>
}
  • jotai
import { atom } from 'jotai'
const countAtom = atom(0)
function Counter() {
  // 状态及相关事件
  const [count, setCount] = useAtom(countAtom)
  return (
    <h1>
      {count}
      <button onClick={() => setCount(c => c + 1)}>one up</button>
    </h1>
  )
}
  • valtio
import { proxy, useSnapshot } from 'valtio'
const state = proxy({ count: 0, text: 'hello' })
function Counter() {
  const snap = useSnapshot(state)
  return (
    <div>
      {snap.count}
      <button onClick={() => ++state.count}>+1</button>
    </div>
  )

相关建议

  • 如果你需要useState+useContext的替代品,那么jotai非常适合,即少量组件间状态共享。
  • 如果你习惯了redux或喜欢react的自然不可变更新,那么zustand将非常适合。
  • 如果你习惯了vue/ slute /mobx,或者是JS/React的新手,valtio的可变模型将很适合。
  • 如果你在使用 zustand(redux/等不可变数据模型) + immer,建议改用valtio(mobx)
  • mobx有actions概念,而valtio概念更为简单(自由),如果你希望工程更为规范,可以使用mobx,如果是希望工程更为自由便捷,可以使用valtio

以上就是React 状态管理工具优劣势示例分析的详细内容,更多关于React 状态管理工具优劣势的资料请关注其它相关文章!

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。