关于前端:前端状态管理React-状态管理工具如何选

42次阅读

共计 3860 个字符,预计需要花费 10 分钟才能阅读完成。

什么是状态治理?

“状态”是形容应用程序以后行为的任何数据。这可能包含诸如“从服务器获取的对象列表”、“以后抉择的我的项目”、“以后登录用户的名称”和“此模式是否关上?”等值。

家喻户晓,咱们在研发一个 简单利用 的过程中,一套好的 状态治理计划 是必不可少的,既能 晋升研发效率,又能升高研发保护老本 ,那么状态治理计划那么多,它们有什么不同,咱们又该 如何抉择 适宜以后利用的计划呢?

本期将次要就 react 的罕用状态治理计划进行比照剖析,心愿对各位看客有帮忙。

React 状态治理计划

计划介绍
  • hooks context
  • react-redux
  • mobx
  • zustand
  • jotai
  • recoil
  • valtio
计划比照
框架 原理 长处 毛病
hooks context 基于 react hook,开发者可实现内 / 内部存储 1. 应用简略 <br/> 2. 不须要援用第三方库,体积最小 <br/> 3. 反对存储全局状态,但在简单利用中不举荐 <br/> 4. 不依赖 react 上下文,可在组件外调用(内部存储的条件下) 1. context value 发生变化时,所有用到这个 context 的组件都会被从新渲染,基于 content 保护的模块越多,影响范畴越大。<br/> 2. 依赖 Context Provider 包裹你的应用程序,批改 store 无奈在利用最顶层 (App.tsx 层级) 触发渲染 <br/> 3. 受 ui 框架束缚(react)<br/> 4. 依赖 hooks 调用
react-redux Flux 思维,公布订阅模式,听从函数式编程,内部存储 1. 不依赖 react 上下文,可在组件外调用 <br/> 2. 反对存储全局状态 <br/> 3. 不受 ui 框架束缚 1. 心智模型须要一些工夫来了解,特地是当你不相熟函数式编程的时候 <br/> 2. 依赖 Context Provider 包裹你的应用程序,批改 store 无奈在利用最顶层 (App.tsx 层级) 触发渲染
mobx 观察者模式 + 数据截止,内部存储 1. 应用简略 <br/> 2. 不依赖 react 上下文,可在组件外调用 <br/> 3. 反对存储全局状态 <br/> 4. 不受 ui 框架束缚 1. 可变状态模型,某些状况下可能影响调试 <br/> 2. 除了体积绝对较大之外,笔者目前未感觉到较为显著的毛病,3.99M
zustand Flux 思维,观察者模式,内部存储 1. 轻量,应用简略 <br/> 2. 不依赖 react 上下文,可在组件外调用 <br/> 3. 反对存储全局状态 1. 框架自身不反对 computed 属性,但可基于 middleware 机制通过大量代码间接实现 computed,或基于第三方库 zustand-computed 实现 <br/> 2. 受 ui 框架束缚(react / vue)
jotai 基于 react hook,外部存储 1. 应用简略 <br/> 2. 组件颗粒度较细的状况下,jotai 性能更好 <br/> 3. 反对存储全局状态,但在简单利用中不举荐 1. 依赖 react 上下文,无奈组件外调用,相对而言, zustand 在 react 环境外及全局能够更好地工作 <br/> 2. 受 ui 框架束缚(react)
recoil 进阶版 jotai, 基于 react hook + provider context,外部存储 绝对于 jotai 而言,会更重一些,但思维根本不变,领有一些 jotai 未反对的个性及 api,如:<br/> 1. 监听 store 变动 <br/> 2. 针对 atom 的操作领有更多的 api,编程上领有更多的可能性,更加乏味 领有 jotai 所有的毛病,且绝对于 jotai 而言:<br/> 1. 应用 recoil 须要 < RecoilRoot > 包裹应用程序 <br/> 2. 编写 selector 会简单一些
valtio 基于数据劫持,内部存储 1. 应用简略,类 mobx(类 vue)的编程体验 <br/> 2. 反对存储全局状态 <br/> 3. 不依赖 react 上下文,可在组件外调用 <br/> 4. 不受 ui 框架束缚 1. 可变状态模型,某些状况下可能影响调试 <br/>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>
    )
    }
  • recoil

    const fontSizeState = atom({  
    key: 'fontSizeState',  
    default: 14,  
    });
    function FontButton() {const [fontSize, setFontSize] = useRecoilState(fontSizeState);  
    return (<button onClick={() => setFontSize((size) => size + 1)} style={{fontSize}}>  
        Click to Enlarge  
      </button>  
    );  
    }
  • 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
  • recoiljotai 的编程思维相似,但提供了更多的 api 与 个性,针对原子状态领有更多的可操作性,同时包体积也更大,但因为 recoil 性能宏大,其应用绝对于 jotai 会繁琐一些, 如果你希望工程 笨重便捷 能够选用 jotai,如果你想试试原子状态更多的可能性,那么试试recoil 吧。

如果该文章对你有帮忙,请给我点个👍吧~
下期将带来 Vue 状态管理工具优劣势剖析, 欢送关注我的 Blog 🌟

正文完
 0