zustand
zustand
2023-10-18|最后更新: 2024-2-5
type
status
date
slug
summary
tags
category
icon
password
Blocking
Blocked by
top
URL
Sub-item
Parent item

Provider + Context(useContext)

一个完整的例子
context 可以实现基础的状态共享。步骤:
  1. 通过createContext创建一个Context,并设置默认值。
  1. Context 中的值都在 Provider 的作用域下有效。所以在最外层包一个 Provider,value中设置传递值。
  1. 如果子组件需要时,则通过 React.useContext拿到Context值。
缺点:
  1. 重复渲染,性能差
当 Context 中的某个属性发生变化时,所有使用该 Context 的子组件都会被重新渲染,即使某些组件可能并未使用到这个属性。
这种问题有两种解决方法:
  1. React.memo 和 shouldComponentUpdate 这两种方式来解决。
  1. 将一个大型的 Context 拆分成多个小的 Context,可以精细地控制每个 Context 的更新,从而减少整个应用程序的重新渲染次数,提高性能和用户体验。
  1. 数据变更方法难以维护
为了保证数据变更方法的可维护性与 action 的不变性,有两种方法但各有问题:使用自定义 hooks,但为了不会重复渲染,每个修改方法需要使用useCallback,需要声明依赖,会造成极大的心智负担。使用useReducer,不支持异步函数、不支持内部的 reducer 互相调用,不支持和其他 state 联动(比如要当参数传进去才可用)。
  1. 使用范围限制
context的store只能在react中使用,无法在外部函数使用,例如请求函数中需要store中的属性,不能直接在请求函数中调用,就只能通过react中作为参数传递。
  1. 无法处理异步请求。
对于异步的逻辑,Context API并没有提供任何API,需要自己做封装。
  1. 无法处理数据间的联动
Context API并没有提供API来生成派生状态,同样也需要自行去封装一些方法来实现。

Redux

优点

  • Redux轻量,生态丰富,可以结合流行的redux-thunkredux-saga等进行使用
  • Redux的写法比较固定,团队应用中风格比较稳定,提高协作中的可维护性
  • 因为Redux中的reducer更新时,每次return的都是不可变对象,所以时间旅行操作相对容易

缺点

  1. 要写大量的模板语言,一个操作定义action类型、而类型还是字符串,写对应ts类型,reducer定义里实现action的操作、store。
  1. 需要通过context providers包裹组件来实现重新渲染。
  1. 很多功能都不具备,很多功能需要引入中间件,例如异步、副作用。学习成本很高。
  1. 通过<Provider/> 单项数据流,没有数据向上回溯的能力,只能向下分发。

Zustand

优点

轻量级

与 Redux 相比,Zustand 的包大小更小。

状态共享

context需要在最外层包一个 Provider。 Context 中的值都在 Provider 的作用域下有效。而 zustand默认是单例模式, 不需要 Provider。直接声明一个 hooks 式的 useStore 后就可以在不同组件中进行调用。
如果需要多实例的话,zustand 也提供了对应的 Provider 的书写方式,

状态变更

  1. 函数可以直接写,完全不用区分同步或者异步。
  1. zustand 会默认将所有的函数保持同一引用。用 zustand 写的方法,默认都不会造成额外的重复渲染。
  1. 更好的状态内聚性,可以互相调用,不用再重新声明函数。

状态派生

  1. zustand 用了类似 redux selector 的方法,实现相应的状态派生。
  1. 可以实现只有监听的属性变化,才会重新渲染

状态组合

可以将相关的状态进行组合,结合中间件实现对单个状态组合进行一些操作,例如对状态组合实现持久化,缓存到localStorage

多环境集成

可以不在 react 环境内直接获取状态数据

性能优化

利用 zustand 的 selector,将得到的对象聚焦到我们需要的对象,只监听这几个对象的变化即可。

支持中间件

  1. devtools,可以将redux的devtools
  1. localstorage,可以直接缓存属性。
 
 
封装库实现原理总结(wip)redux
Loading...