React+valtio响应式状态管理
Valtio 是一个很轻量级的响应式状态管理库。valtio 让数据管理在 React 和原生 JS (Vanilla
) 中变得更加简单的一个库,它类似于 Vue 的数据驱动视图的理念,使用外部状态代理去驱动 React 视图来更新。
一、状态管理库
dispatch
流派(单向数据流-中心化管理):redux
、zustand
、dva
等- 响应式流派(中心化管理):
mobx
、valtio
等 - 原子状态流派(原子组件化管理):
recoil
、jotai
等
值得一提的是:Jotai
、Zustand
、Valtio
这三个开源状态管理库都是出自一人之手。
zustand 德语 “状态”,jotai 日语 “状态”、valtio 芬兰语 “状态”。
作者叫做 Daishi Kato,他是日本东京人,是个全职开源作者。
二、Jotai、Zustand、Valtio 使用对比
- Zustand
import { create } from "zustand"; const useStore = create((set) => ({ count: 0, inc: () => set((state) => ({ count: state.count + 1 })), })); export default function Counter() { const count = useStore((state) => state.count); const inc = useStore((state) => state.inc); return ( <div> {count} <button onClick={inc}>+1</button> </div> ); }
- Jotai:每个状态都是原子化,用法和原生的 useState 有点像
import { atom, useAtom } from "jotai"; const countAtom = atom(0); function Counter() { const [count, setCount] = useAtom(countAtom); return ( <div> {count} <button onClick={() => setCount((v) => v + 1)}>+1</button> </div> ); }
- Valtio:和 Vue 的响应式类似,当数据发生变化的时候就驱动视图更新
const state = proxy({ dur: 10, count: 1102 }); const incDur = () => {++state.dur}; const decDur = () => {--state.dur}; const incCount = () => { ++state.count; setTimeout(incCount, 100 * state.dur); }; incCount(); export default function Main() { const snap = useSnapshot(state) return ( <div> <h3>{snap.dur}</h3> <button disabled={snap.dur <= 1} onClick={decDur}> - </button> <button disabled={snap.dur >= 10} onClick={incDur}> + </button> </div> ); }
三、Valtio 状态管理最佳实践
- 创建一个
store.js
文件
import { proxy } from 'valtio' import { useProxy } from 'valtio/utils' import { cloneDeep } from 'lodash-es' export const defaultData = { activeIndex: 0, rangeData: [5, 20], baseSelected: [], step: { 1: true, 2: false, 3: false, 4: false, 5: false, 6: false, }, } const state = cloneDeep(defaultData) const store = proxy(state) export const useStore = () => { return useProxy(store) } export function resetData() { Object.entries(defaultData).forEach( ([key, value]) => { store[key] = cloneDeep(value) } ) }
- 在组件中使用
import { useStore, resetData } from '@/store/store' const tabs = [ { value: '1', label: '基础设置', }, { value: '2', label: '高级设置', }, { value: '3', label: '其他设置', } ] const list = [ { value: '1', label: '标签' }, { value: '2', label: '分类' }, { value: '3', label: '作者' }, ] export default function Main() { const store = useStore() useEffect(() => { return () => { // 在组件卸载的时候重置数据 resetData() } }, []); function onSelect(id) { if (store.baseSelected.includes(id)) { store.baseSelected = store.baseSelected.filter( (item) => item !== id ) } else { if (store.baseSelected.length >= 5) return store.baseSelected.push(id) } } return ( <div> { tabs.map(({ value, label }, index) => ( <div key={value} onClick={() => { store.activeIndex = index }} > {label} </div> )) } <hr/> { list.map(({ value, label }) => ( <div key={value} onClick={() => { onSelect(value) }} > {label} </div> )) } </div> ); }
useProxy
其实就是对取 useSnapshot()
或 store
数据的封装,这个 hook 也很简单,就是判断是渲染期间(渲染体内)就返回 useSnapshot()
的快照数据,非渲染期间(非渲染体内)就返回原始的 store 数据,和我们自己手写的是差不多的,只不过这个 hook 帮我们把这个过程封装了起来。
到此这篇关于React+valtio响应式状态管理的文章就介绍到这了,更多相关React valtio响应式状态内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
react-native ListView下拉刷新上拉加载实现代码
本篇文章主要介绍了react-native ListView下拉刷新上拉加载实现,具有一定的参考价值,感兴趣的小伙伴们可以参考一下2017-08-08react进阶教程之异常处理机制error Boundaries
在react中一旦出错,如果每个组件去处理出错情况则比较麻烦,下面这篇文章主要给大家介绍了关于react进阶教程之异常处理机制error Boundaries的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下2022-08-08React Native基础入门之调试React Native应用的一小步
这篇文章主要给大家介绍了关于React Native基础入门之调试React Native应用的相关资料,文中通过图文介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2018-07-07React脚手架config-overrides.js文件的配置方式
这篇文章主要介绍了React脚手架config-overrides.js文件的配置方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教2023-10-10
最新评论