zustandjotai 是当下比较流行的react状态管理库。其都有着轻量、方便使用,和react hooks能够很好的搭配,并且性能方面,对比React自身提供的context要好得多,因此被很多开发小伙伴所喜爱。

更有意思的是,这两个库的作者是同一个人,同时他还开源了另外一个状态库 valtio,并没来得及研究(表示卷不动了),这三个库的实现思路却是不同的,号称是以一己之力搅乱React 状态库生态圈的人。

Comparison: https://docs.pmnd.rs/zustand/getting-started/comparison

注:文中如有理解不正确点,可以随意指出。 图片如果看不清,可以私信我发。

zustand

zustand的实现原理相对简单,全局生成一个store,提供getState,setState以及subscribe,因此天然和React 18提供的useSyncExternalStore配合使用。

大致的原理:当set状态之后,useStore中会监听整个store的变化,然后同步组件中的状态,使受影响的组件重新更新。

BestPractise & 优化

通过代码分析,如果不想做一些无意义的render,推荐使用selector。使用selector主要有两个方面的优点:

  • 只返回组件自身关注的state,如果state没有变化,组件不会刷新,否则一旦store变化,state没有变化的组件也会随之刷新
  • 由于useSyncExternalStoreWithSelector本身提供的getSelection方法带有缓存效果,如果两次的snapshot相同,则不会进行selector的重复计算,这对于selector中如果本身有复杂逻辑的无疑是有性能优化的。
  • zustand是基于immutable数据的改变来引起组件重新渲染的,记得不要直接在对象中改值,而是返回一个全新的对象,这点可以配合 immer 使用,zustand也提供了相应的 middleware
  • best parctise

jotai

jotai的理解难度相对而言就难一些,jotai推崇原子化,通过基础的atom派生出更复杂等级的atom,因此jotai天然支持computed属性,对于zustand而言,想要实现computed属性,则需要魔改setState来达到目的。

原理

  • readAtom的时候,会顺次生成这个原子的依赖,维护在自身atomStated(depedencies)中,这将形成一个树形链表。
  • subscribleAtom的时候,会根据该原子的依赖项,生成dependent,这样做的目的是当该原子进行重新设值时,能够根据他的dependent来重新计算依赖它的原子的值,dependent会维护在mountedMap中,只有当sub之后,Atom才会被加入到mountedMap中。
  • writeAtom时,会根据mountedMap中的dependent,重新计算收到影响的原子,并且调用该原子的以及在mountedMap中受到影响的原子的listeners,这样会触发组件中收到影响的原子重新获取到最新的值。
  • 在React部分就相对简单一些,Provider维持一个全局的store,方便各个useAtomValue进行subuseAtomValue会监听原子的变化,从而进行rerender,以便获取到最新的值。useSetAtom调用writeAtom

BestPractise

搜了一圈,官网好像没有最佳实践的建议,个人根据一些理解,提出一些:

  • atom应该尽量小,每个原子尽量做的事情比较单一,不然全局一个atom进行subscribe并没有意义
  • 相关的atom原子应该尽量在维护在一个文件中,避免不必要的上下文切换,使得代码变得难以理解
  • 对于比较复杂的逻辑,通过派生原子或者组合原子的方式来维护
  • 只需要更新atom的时候,只需要调用useSetAtom就好,不subscribe就意味着不需要关心该atom的变化,从而不会引起不必要的更新

总结

没有总结,卷不动了。

两张图带你全面了解React状态管理库:zustand和jotai的更多相关文章

  1. 借鉴redux,实现一个react状态管理方案

    react状态管理方案有很多,其中最简单的最常用的是redux. redux实现 redux做状态管理,是利用reducer和action实现的state的更新. 如果想要用redux,需要几个步骤 ...

  2. React状态管理相关

    关于React状态管理的一些想法 我最开始使用React的时候,那个时候版本还比较低(16版本以前),所以状态管理都是靠React自身API去进行管理,但当时最大的问题就是跨组件通信以及状态同步和状态 ...

  3. 比Redux更容易上手的状态管理库

    前言 当项目越发复杂时,我们发现仅仅是提升状态已经无法适应如此复杂的状态管理了,程序状态变得比较难同步,操作,到处是回调,发布,订阅,这意味着我们需要更好的状态管理方式,于是就引入了状态管理库,如Re ...

  4. 记前端状态管理库Akita中的一个坑

    记状态管理库Akita中的一个坑 Akita是什么 Akita是一种基于RxJS的状态管理模式,它采用Flux中的多个数据存储和Redux中的不可变更新的思想,以及流数据的概念,来创建可观察的数据存储 ...

  5. vue组件化开发-vuex状态管理库

    Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化.Vuex 也集成到 Vue 的官方调试工具 ...

  6. 轻量级状态管理库Pinia试吃

      最近连续看了几个GitHub上的开源项目,里面都用到了 Pinia 这个状态管理库,于是研究了一下,发现确实是个好东西!那么,Pinia 的特点: 轻量化 -- Pinia 体积约1KB,十分轻巧 ...

  7. 纯粹极简的react状态管理组件unstated

    简介 unstated是一个极简的状态管理组件 看它的简介:State so simple, it goes without saying 对比 对比redux: 更加灵活(相对的缺点是缺少规则,需要 ...

  8. react状态管理器之mobx

    react有几种状态管理器,今天先来整理一下mobx状态管理器,首先了解一下什么是mobx 1.mobx成员: observable action 可以干嘛: MobX 的理念是通过观察者模式对数据做 ...

  9. SDWebImage实现原理--两张图带你看懂

    SDWebImage底层实现有沙盒缓存机制,主要由三块组成:1.内存图片缓存,2.内存操作缓存,3.磁盘沙盒缓存 SDWebImage GitHub地址 版本4.0.0 一.SDWebImage时序图 ...

  10. react状态管理器(分模块)之redux和redux + react-redux + reducer和redux + react-redux + reducer分模块 + 异步操作redux-thunk

    1.回顾 cnpm i redux react-redux redux-thunk -S store/index.js src/index.js src/views/home/index.jsx + ...

随机推荐

  1. TCP/IP协议栈及网络基础

    TCP/IP协议栈及网络基础 目录 TCP/IP协议栈及网络基础 1. TCP/IP协议栈及网络基础 1.1 OSI网络模型 1.2 TCP/IP网络模型 1.2.1 物理层 1.2.2 数据链路层 ...

  2. 传入一个List集合,返回分页好的数据

    传入一个List集合,返回分页好的数据. 定义分页信息类: package com.cn.common; import java.util.List; public class CommonPage& ...

  3. leaflet 根据一个经纬度及距离角度,算出另外一个经纬度

    /** * 根据一个经纬度及距离角度,算出另外一个经纬度 * @param {*} lng 经度 113.3960698 * @param {*} lat 纬度 22.941386 * @param ...

  4. uniapp关于uni.getUserProfile的使用

    点击查看代码 <button @click="getMy" data-eventsync="true">获取信息</button> le ...

  5. Chrome 插件 V3 版本 Manifest.json 中的内容脚本(Content Scripts)解析

    内容脚本(Content Scripts) 指定在用户打开某些网页时要使用的 JavaScript 或 CSS 文件. 内容脚本是在网页环境中运行的文件.通过使用标准文档对象模型 (DOM),开发者能 ...

  6. 记一次ThreadLocal中的用户信息混乱问题

    前言 记录一次开发中遇到的关于 ThreadLocal 问题,场景是数据库表中的操作人总是无缘无故的被更改,排查了几遍代码才发现是 ThreadLocal 没有及时清理导致的. 一.为什么使用 Thr ...

  7. IPv6 — 基于邻居发现协议的通信方式

    目录 文章目录 目录 前文列表 IPv6 的通信方式 NDP(Neighbor Discovery Protocol,邻居发现协议) IPv6 地址自动配置 无状态自动配置概述 前文列表 <IP ...

  8. 4G EPS 中的小区选择

    目录 文章目录 目录 前文列表 小区选择 RSRP(参考信号接收功率) RSRQ(参考信号接收质量) RSSI(接收信号强度指示) SINR(信号与干扰加噪声比) 前文列表 <4G EPS 中的 ...

  9. PageOffice6最简集成代码(Asp.Net)

    本文描述了PageOffice产品在普通的Asp.Net项目中如何集成调用. 新建Asp.Net项目:PageOffice6-Net-Simple 在您的web项目的"依赖项-包-管理NuG ...

  10. JavaScript字符串对象转JSON格式

    JavaScript字符串对象转JSON格式 原始数据                 {  xAxis: {    type: 'category',    data: ['Mon', 'Tue', ...