在React状态管理方案中,Zustand以其简洁的API和易用性受到越来越多开发者的青睐。本文将通过两个实际案例,带大家掌握Zustand的核心用法,包括计数器状态管理和API数据获取,同时展示多仓库的组织方式。
为什么选择Zustand?
相比Redux的繁琐配置和Context API的性能问题,Zustand具有以下优势:
-
无需Provider包裹应用
-
简洁的API设计,学习成本低
-
支持中间件和持久化
-
良好的TypeScript支持
-
可以创建多个独立仓库
下面我们通过两个实际仓库的实现,来感受Zustand的魅力。
在项目中安装Zustand执行 npm install zustand即可啦
项目结构设计
首先看一下我们的项目结构,主要包含两个核心仓库和三个组件:
实现计数器仓库(count.js)
我们先实现一个简单的计数器仓库,用于管理count和age两个状态,以及对应的修改方法。
// src/store/count.js
import { create } from 'zustand'
const useCountStore = create((set) => ({
// 状态数据
count: 0,
age: 18,
// 修改数据的方法,自增1
increase: () => set((state) => ({ count: state.count + 1 })),
// 带参数的修改方法
decrease: (val) => {//减少指定值val
return set((state) => ({ count: state.count - val }))
}
}))
export default useCountStore
这个仓库包含:
-
两个状态:count(计数器值)和age(年龄,默认18)
-
两个方法:increase(自增1)和decrease(减少指定值)
实现Home和About组件
Home组件(计数器操作界面)
Home组件负责提供计数器的操作按钮,通过调用仓库的方法来修改状态:
// src/components/Home.jsx
import React from 'react'
import useCountStore from '../store/count.js'
export default function Home() {
// 从仓库获取状态和方法
const count = useCountStore((state) => state.count)
const increase = useCountStore((state) => state.increase)
const decrease = useCountStore((state) => state.decrease)
return (
//点击按钮直接调用仓库里面的方法,不用传参
<button onClick={increase}>增加-{count}</button>
<button onClick={() => decrease(10)}>减少</button>
)
}
About组件(计数器展示界面)
About组件只负责展示count状态,不包含修改逻辑:
// src/components/About.jsx
import React from 'react'
import useCountStore from '../store/count.js'
export default function About() {
// 只获取需要的count状态,从仓库获取count,Home改了这里自动会更新
const count = useCountStore((state) => state.count)
return (
title --{count}
)
}
可以看到,Home和About组件通过count仓库实现了状态共享,无需通过props传递数据。
实现列表数据仓库(list.js)
接下来我们实现第二个仓库,用于管理API获取的列表数据:
// src/store/list.js
import { create } from "zustand";
// 封装API请求
const fetchApi = async() => {
//async函数的return会变成Promise的resolve值
const response = await fetch('https://mock.mengxuegu.com/mock/66585c4db462b81cb3916d3e/songer/songer')
const res = await response.json()
return res.data
}
//构造一个存列表的仓库
const useListStore = create((set) => ({
list: [], // 初始化为空数组
// 获取列表数据的方法
fetchList: async() => {
const res = await fetchApi()
set({ list: res }) // 更新列表数据
}
}))
export default useListStore
这个仓库负责:
-
存储列表数据(list状态)
-
提供获取数据的方法(fetchList)
实现List组件
List组件使用list仓库来获取和展示数据:
// src/components/List.jsx
import React, { useEffect } from 'react'
import useListStore from '../store/list.js'
export default function List() {
// 获取列表数据和获取方法
const list = useListStore(state => state.list)
const fetchList = useListStore(state => state.fetchList)
// 组件挂载时获取数据
useEffect(() => {
fetchList()
}, [fetchList])
return (
<div>
{
//将数据Map遍历
list.map((item) => (
<div key={item.id}>
{item.name}
</div>
))
}
</div>
)
}
整合到App组件
最后我们在App组件中整合这些组件:
// src/App.jsx
import React from 'react'
import Home from './components/Home.jsx'
import About from './components/About.jsx'
import List from './components/List.jsx'
export default function App() {
return (
<Home />
<About />
<List />
)
}
总结
通过本文的两个案例,我们学习了:
-
如何创建Zustand仓库(count仓库和list仓库)
-
如何在组件中使用仓库的状态和方法
-
多仓库的组织方式(按功能划分不同仓库)
-
如何处理同步状态(计数器)和异步数据(API请求)
Zustand的简洁设计让状态管理变得简单,同时又保持了足够的灵活性。在实际项目中,我们可以根据功能模块划分多个仓库,使状态管理更加清晰。
希望本文对你理解Zustand有所帮助,快去你的项目中尝试使用吧!