React 使用 Zustand 详细教程

前言

Redux、MobX 和 Context API 等技术的存在,使得管理大型应用的状态变得更加可行。本教程要深入探讨的是 Zustand —— 一个极简且高效的状态管理库,详细介绍如何在 React 项目中使用 Zustand 来管理状态。

什么是 Zustand?

Zustand 是一个简单、小体积(只有不到1kB)且性能优异的状态管理库,它使用了现代 React 的钩子(hooks)特性。Zustand 的设计哲学是使状态管理尽可能简单,无需使用 reducers、middlewares 或者复杂的配置,简直是小项目和快速原型开发的福音。

基础使用步骤

1. 安装 Zustand

首先,你需要在你的 React 项目中安装 Zustand。打开你的终端,并运行以下命令:

npm install zustand

或者,如果你使用yarn:

yarn add zustand

2. 创建一个简单的状态存储

创建 Zustand 状态存储非常直接。让我们来创建一个简单的计数器示例:

import create from 'zustand'const useStore = create(set => ({count: 0,increment: () => set(state => ({ count: state.count + 1 })),decrement: () => set(state => ({ count: state.count - 1 }))
}));export default useStore;

在这里,我们使用 create 函数从 Zustand 引入并初始化状态。这个函数接受一个设置函数,该函数带有一个 set 方法,可用于更新状态。

3. 在组件中使用状态

有了状态存储,我们可以在任何 React 组件中使用它。这里是如何在一个组件中使用上面创建的计数器:

import React from 'react';
import useStore from './store';function Counter() {const { count, increment, decrement } = useStore();return (<div><h1>{count}</h1><button onClick={increment}>Increment</button><button onClick={decrement}>Decrement</button></div>);
}export default Counter;

在这个 Counter 组件中,我们通过调用 useStore() 钩子来访问存储的状态和方法。然后,我们可以直接在 JSX 中使用这些状态,并绑定 incrementdecrement 方法到按钮的点击事件。

高级用法

1. 日志中间件

Zustand 还支持中间件、异步操作和拆分状态等更高级的用法。例如,使用中间件记录所有状态更新:

import create from 'zustand'
import { devtools } from 'zustand/middleware'const useStore = create(devtools(set => ({count: 0,increment: () => set(state => ({ count: state.count + 1 })),decrement: () => set(state => ({ count: state.count - 1 }))
})));export default useStore;

在这里,我们使用 devtools 中间件,它允许你在 Redux DevTools 中查看状态变化。

2. 异步操作

Zustand 也支持在状态管理中处理异步操作。这对于处理例如从 API 加载数据等场景非常有用。我们来看一个实现异步操作的例子:

import create from 'zustand'const useStore = create(set => ({userData: {},fetchUserData: async (userId) => {const response = await fetch(`https://api.example.com/user/${userId}`);const data = await response.json();set({ userData: data });}
}));export default useStore;

在这个例子中,我们在状态存储中添加了一个 fetchUserData 异步函数,它从某个 API 获取用户数据并更新状态。在组件中使用它非常简单:

import React, { useEffect } from 'react';
import useStore from './store';function UserProfile({ userId }) {const { userData, fetchUserData } = useStore();useEffect(() => {fetchUserData(userId);}, [userId, fetchUserData]);return (<div><h1>User Profile</h1><p>Name: {userData.name}</p><p>Email: {userData.email}</p></div>);
}export default UserProfile;

UserProfile 组件中,我们使用了 useEffect 钩子来在组件挂载时调用 fetchUserData。这样每当用户 ID 改变时,我们都会重新获取用户数据。

3. 状态分割

随着应用的增长,全部状态放在单一存储中可能变得难以管理。Zustand 允许我们通过分割状态来解决这个问题,使得每部分状态都有自己的逻辑和责任范围。让我们来看一个状态拆分的例子:

import create from 'zustand'const useUserStore = create(set => ({users: [],addUser: user => set(state => ({ users: [...state.users, user] }))
}));const useProductStore = create(set => ({products: [],addProduct: product => set(state => ({ products: [...state.products, product] }))
}));export { useUserStore, useProductStore };

在这个例子中,我们创建了两个独立的存储:一个用于用户数据,另一个用于产品数据。在大型应用中,这种模式可以帮助我们更好地组织代码和逻辑。

总结

Zustand 的灵活且强大的功能使其成为现代 React 应用中管理状态的极佳选择。通过简单的 API,支持异步操作和状态拆分,Zustand 不仅能满足小型项目的需求,也能轻松应对复杂的大型应用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/28444.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

现在的AI大模型,业已进入到泛滥成灾的发展阶段

我们都知道&#xff0c;现在的AI大模型&#xff0c;可以说&#xff0c;业已进入到泛滥成灾的发展阶段。 但凡是一个科技玩家&#xff0c;基本上都会推出自己的大模型。 从某种意义上来讲&#xff0c;AI大模型业已成为一个前瞻性的战略角色&#xff0c;蜕变成为了一种标配角色…

guli商城业务逻辑-基础篇笔记

这里写目录标题 0.1 viscode设置用户代码片段1.实现多级菜单接口1.1 对接前端菜单1.2 对接网关接口解决跨域问题&#xff0c;如果不解决跨域&#xff0c;浏览器还是访问不了api1.3 把商品服务添加网关1.4 修改前端显示分类菜单1.5 给菜单添加删除修改功能1.5.1 删除功能的后端业…

Oracle 入门--前提

目录 1.sqlplus 2.dual是什么&#xff1f; 3.SQL语句的种类 4.Oracle是如何工作的 5.Oracle查看配置文件 6.修改配置文件 7.常用的参数设置 1.sqlplus 管理数据库&#xff1a;启动&#xff0c;关闭&#xff0c;创建&#xff0c;删除对象......查看数据库的运行状态&…

【分布式计算】java消息队列机制

消息队列是一种在不同组件或应用之间进行数据传递的技术&#xff0c;通常用于处理异步通信。它允许消息的发送者&#xff08;生产者&#xff09;和接收者&#xff08;消费者&#xff09;之间进行解耦。 概念 消息队列是一种先进先出&#xff08;FIFO&#xff09;的数据结构&…

中介子方程二十

X$XFX$XEXyXαXiX$XαXiXrXkXtXyX$XpXVX$XdXuXWXπX$XWXyXWX$XπXWXuXdX$XVXpX$XyXtXkXrXiXαX$XiXαXyXEX$XFX$XEXyXαXiX$XαXiXrXkXtXyX$XpXVX$XdXuXWXπX$XWXyXWX$XπXWXuXdX$XVXpX$XyXtXkXrXiXαX$XiXαXyXEX$XαXηXtXαX$XWXyX$XyXWX$XpXαXqXηX$XeXαXhX$XdX$XpX$XdX$…

Web前端开发12章:深入探索与实战解析

Web前端开发12章&#xff1a;深入探索与实战解析 在数字化浪潮的推动下&#xff0c;Web前端开发技术日新月异&#xff0c;成为了构建互联网应用的重要基石。本文将以12章的篇幅&#xff0c;从四个方面、五个方面、六个方面和七个方面&#xff0c;深入探索Web前端开发的精髓&am…

【INTEL(ALTERA)】Nios® II无法使用基于 Ubuntu 18.04.5 的 WSL 进行构建

现象 在使用 Ubuntu 18.04.5 构建 WSL 的Nios II处理器时&#xff0c;任何英特尔 Quartus Prime 软件版本都可能会看到此问题。 原因 这是因为在 Nios II Command Shell 中运行命令 “wslpath -u .”时返回值不同。 正常工作&#xff1a;命令返回”。故障&#xff1a;命令返回…

机器学习(V)--无监督学习(一)聚类

根据训练样本中是否包含标签信息&#xff0c;机器学习可以分为监督学习和无监督学习。聚类算法是典型的无监督学习&#xff0c;目的是想将那些相似的样本尽可能聚在一起&#xff0c;不相似的样本尽可能分开。 相似度或距离 聚类的核心概念是相似度(similarity)或距离(distance…

PyTorch 拼接与拆分-Tensor基本操作

拼接&#xff1a; cat, stack … 使用 cat 在指定维度 dim 上拼接: torch.cat(element_list, dim) >>> a torch.rand(2,3) >>> b torch.rand(1,3) >>> c torch.cat([a,b], dim0) >>> c.shape torch.Size([3, 3])使用 stack 在新增维…

嵌入式学习记录6.14(练习)

#include "mainwindow.h" #include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow) {ui->setupUi(this);this->resize(1028,783); //设置左侧背景QLabel *lab1new QLabel(this);lab1->…

uniapp使用vue3打包H5,android或ios加载白屏

前景介绍 按照uniapp官方文档介绍&#xff0c;根据步骤创建了使用Vue3的项目&#xff1b;执行命令npm run build:h5, 本地安装了http-server&#xff0c;打包之后的dist文件夹&#xff0c;执行http-server后&#xff0c;可以访问&#xff1b; 但是使用Android或者ios进行本地加…

【内存管理之堆内存】

1.栈上的基元 2.栈上的聚合对象 3.手动分配和释放 4.分配堆内存 5.数组内存分配和释放 6.数组内存分配 7.不要使用野指针 8.黑暗时代

STM32理论 —— μCOS-Ⅲ(2/2):时间管理、消息队列、信号量、任务内嵌信号量/队列、事件标志、软件定时器、内存管理

文章目录 9. 时间管理9.1 OSTimeDly()9.2 OSTimeDlyHMSM()9.3 OSTimeDlyResume()9.4 延时函数实验 10. 消息队列10.1 创建消息队列函数OSQCreate()10.2 发送消息到消息队列函数(写入队列)OSQPost()10.3 获取消息队列中的消息函数(读出队列)OSQPend()10.4 消息队列操作实验 11. …

12 款 Android 照片恢复应用程序列表

丢失难忘的照片总是令人痛苦的。如果软件崩溃或意外删除&#xff0c;Android 设备上的照片也可能会丢失。这时照片恢复应用程序就派上用场了。查看我们为 Android 收集的顶级照片恢复应用程序。 但是&#xff0c;您不会想为自己选择任何照片恢复应用程序。因此&#xff0c;我们…

解决小程序的异步请求问题

解决小程序的异步请求问题&#xff0c;可以从多个方面入手&#xff0c;以确保请求的顺畅执行和错误处理。以下是一些主要的解决方法和策略&#xff1a; 1. 确保网络连接正常 检查网络连接&#xff1a;首先&#xff0c;确保用户的设备已连接到互联网&#xff0c;并且网络连接稳…

Doris:冷热分层

目录 一、冷热分层介绍 二、存储策略&#xff08;Storage policy&#xff09; 2.1 创建存储资源 2.2 创建存储策略 2.3 使用存储策略 三、使用限制 一、冷热分层介绍 冷热分层支持所有 Doris 功能&#xff0c;只是把部分数据放到对象存储上&#xff0c;以节省成本&am…

openGauss 6.0.0 一主二备集群安装及使用zcbus实现Oracle到openGauss的数据同步

一、前言 openGauss 6.0.0-RC1是openGauss 2024年3月发布的创新版本&#xff0c;该版本生命周期为0.5年。根据openGauss官网介绍&#xff0c;6.0.0-RC1与之前的版本特性功能保持兼容,另外&#xff0c;在和之前版本兼容的基础上增加了很多新功能&#xff0c;比如分区表性能优化…

go的netpoll学习

go的运行时调度框架简介 Go的运行时&#xff08;runtime&#xff09;中&#xff0c;由调度器管理&#xff1a;goroutine&#xff08;G&#xff09;、操作系统线程&#xff08;M&#xff09;和逻辑处理器&#xff08;P&#xff09;之间的关系 以实现高效的并发执行 当一个gorout…

统计完全子字符串

很不错的计数问题&#xff0c;用到了分组循环技巧和滑动窗口 代码的实现方式也非常值得多看 class Solution { public:int f(string s,int k){int res 0;for(int m1;m<26&&k*m<s.size();m){int cnt[27]{};auto check[&](){for(int i0;i<26;i){if(cnt[i]…

跟着刘二大人学pytorch(第---10---节课之卷积神经网络)

文章目录 0 前言0.1 课程链接&#xff1a;0.2 课件下载地址&#xff1a; 回忆卷积卷积过程&#xff08;以输入为单通道、1个卷积核为例&#xff09;卷积过程&#xff08;以输入为3通道、1个卷积核为例&#xff09;卷积过程&#xff08;以输入为N通道、1个卷积核为例&#xff09…