zustand 状态管理库的使用 结合TS

zustand 是一个用于React应用的简单、快速且零依赖的状态管理库。它使用简单的钩子(hooks)API来创建全局状态,使得在组件之间共享状态变得容易。
React学习Day10

基本用法

  1. 安装:首先,你需要安装zustand库。

    npm install zustand
    
  2. 创建一个状态存储:使用createStore函数来创建一个新的状态存储。

  3. 设置初始状态:你可以提供一个对象作为初始状态,对象的每个属性都将成为状态的一部分。

  4. 定义状态更新函数:这些函数可以修改状态存储中的状态。

  5. 使用状态:在组件中使用useStore钩子来访问和更新状态。

代码示例

以下是一个使用zustand的基本示例:

store / user.tsx 中创建一个状态

import { create } from "zustand";

interface Store {
  count: number;
  inc: (num: number) => void;
}
// 这里的 <Store> 表示 create 函数接受一个泛型参数,这个参数是 Store 接口的类型。
// 相当于在调用函数的时候指定type参数,类似 fun1<number>(1);
const createUserStore = create<Store>((set) => {
  return {
    count: 0,
    inc: (num: number) => {
      set((state) => ({ count: state.count + num }));
    },
  };
});



export default createUserStore;

在组件中使用这个状态
component / Son.tsx

import React from "react";
import createUserStore from "../store/user";  // 引入

interface SonProps {
  data: number; 
  changeFatherMoney: (data: number) => void; 
}

const Son: React.FC<SonProps> = ({ data, changeFatherMoney }) => {
  const { count, inc } = createUserStore();  // 导出
  return (
    <div style={{ border: "1px red solid" }}>
      <div>用户信息counter:{count}</div>
      <button
        onClick={() => {
          inc(10);
        }}
      >
        +10
      </button>
      <p>这里是子组件</p>
      父亲的数据是:{data}
      <button onClick={() => changeFatherMoney(data - 1)}>用父亲一块钱</button>
    </div>
  );
};

export default Son

泛型介绍

在TypeScript中,<Store> 是一个泛型参数的表示方式。这里的 <Store> 表示 create 函数接受一个泛型参数,这个参数是 Store 接口的类型。

泛型在TypeScript中是一种强大的方式,允许你为函数、接口或类定义类型参数,这些参数在定义时不必指定具体的类型,而是在使用时指定。这样做可以提高代码的复用性和灵活性。

在你给出的示例中:

interface Store {
  count: number;
  inc: (num: number) => void;
}

const createUserStore = create<Store>((set) => {
  return {
    count: 0,
    inc: (num: number) => {
      set((state) => ({ count: state.count + num }));
    },
  };
});

这里的<Store>泛型,规定了create的返回值类型,返回的状态存储对象的类型,而不是用来规定参数类型。

create 表示 create 函数接受一个泛型参数 Store。这个泛型参数是类型接口 Store,它定义了 store 的形状,即包含 count 和 inc 属性。
在这里不是对泛型参数进行约束,而是直接指定了 create 函数所使用的泛型类型,规定了返回的对象必须是否符合 Store 接口的定义

  • interface Store 定义了一个接口,其中包含一个 count 属性和一个 inc 方法。
  • create<Store>zustandcreate 函数,它被调用时使用了泛型参数 <Store>。这意味着 create 函数将创建一个状态存储,其形状(state shape)将由 Store 接口定义。
  • createUserStore 是一个函数,当调用时会返回一个符合 Store 接口的状态存储实例。

为什么在 Zustand 中使用泛型而不是接口

在 Zustand 的 create 函数中,泛型不仅用于指定返回值的类型,还用于定义函数内部 set 方法的参数类型等,这比单独使用接口来定义返回值类型更具优势。

示例代码
import { create } from "zustand";

interface Store {
  count: number;
  inc: (num: number) => void;
}

const createUserStore = create<Store>((set) => {
  return {
    count: 0,
    inc: (num: number) => {
      set((state) => ({ count: state.count + num }));
    },
  };
});
解释
  1. 泛型的作用

    • create<Store> 中的 <Store> 泛型不仅指定了 createUserStore 的返回值类型,也规定了回调函数参数 set 的类型。
    • set 函数的类型定义需要知道 Store 的结构,以便 TypeScript 可以正确推断 setstate 的类型。
  2. 接口的局限性

    • 如果只使用接口来定义返回值类型,会失去对 set 函数类型的类型推断和约束。
    • 接口无法单独定义 create 函数返回的回调函数 set 的参数类型。
示例:如果只用接口定义返回值类型

如果只用接口定义返回值类型,无法涵盖 set 函数类型的约束:

const createUserStore = create((set: (fn: (state: Store) => Store) => void) => {
  return {
    count: 0,
    inc: (num: number) => {
      set((state) => ({ count: state.count + num }));
    },
  };
} as Store);

这种方式缺乏泛型提供的灵活性和类型推断能力,代码变得不那么优雅,类型定义也不那么清晰。

总结

  1. 泛型用途广泛:泛型不仅可以规定返回值类型,还可以用于函数参数、类属性和方法、接口属性和方法、类型别名等。
  2. Zustand 中使用泛型的优势:在 Zustand 的 create 函数中使用泛型,不仅规定了返回值类型,还涵盖了内部回调函数 set 的参数类型约束,使代码更加类型安全和简洁。
  3. 接口的局限性:仅使用接口来定义返回值类型,无法对函数参数类型进行全面约束,失去了泛型提供的类型推断能力。

通过使用泛型,你可以使代码更具通用性、灵活性和类型安全性,特别是在处理复杂的类型结构时。

调试工具

npm i simple-zustand-devtools -D

import create from 'zustand'

// 导入核心方法
import { mountStoreDevtool } from 'simple-zustand-devtools'

// 省略部分代码...


// 开发环境开启调试
if (process.env.NODE_ENV === 'development') {
  mountStoreDevtool('channelStore', useChannelStore)
}


export default useChannelStore

在这里插入图片描述

注意事项

  • zustand的状态存储是单一的,意味着所有组件共享相同的状态副本。
  • 状态更新是响应式的,组件会在状态变化时重新渲染。
  • 状态存储的创建应该是一次性的,通常在单独的文件中进行,然后被多个组件导入和使用。

zustand是一个轻量级的状态管理解决方案,特别适合中小型项目或者需要快速设置全局状态的场景。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java阻塞队列:DelayQueue

Java阻塞队列&#xff1a;DelayQueue 在Java的并发编程中&#xff0c;阻塞队列是一种非常有用的数据结构&#xff0c;它不仅提供了线程安全的队列操作&#xff0c;还在必要时会自动阻塞获取操作&#xff0c;直到队列变得不为空。本文将重点介绍一种特殊的阻塞队列——DelayQue…

亲测:无影云电脑免费三个月已经缩短为1个月

亲测&#xff1a;无影云电脑免费三个月已经缩短为1个月&#xff0c;大家不要再找3个月的无影云电脑&#xff0c;已经没有了&#xff0c;目前最新消息是1个月。以前可以领3个月&#xff0c;现在只能领1个月&#xff0c;在阿里云免费中心 https://free.aliyun.com/ 大家自己看吧&…

中国各区域人口密度可视化图

原文链接https://mp.weixin.qq.com/s?__bizMzUyNzczMTI4Mg&mid2247674303&idx1&sn830304f80a0429406c4a5e38dc7750ec&chksmfa777682cd00ff9434e4660bb52ab2bf19913b6732083de061664401a9ac0fa46581cd9e5e86&token1445576002&langzh_CN&scene21#we…

StarkNet System Architecture 系统架构

文章目录 Starknet架构排序器,证明器和节点、验证者、Starnet Core排序器 Sequencer证明器 Prover节点验证者StarkNet Core工作原理TransactionsStarknet架构 原文链接: https://david-barreto.com/starknets-architecture-review/#more-4602 StarkNet 有五个组成部分。分别…

Stable Diffusion 秋叶整合包v4.7 :解压即用,快速入门AI绘画

Stable Diffusion秋叶整合包&#xff0c;超简单一键安装Stable Diffusion&#xff0c;无任何使用门槛&#xff0c;完全免费使用&#xff0c;支持Nvdia全系列显卡&#xff0c;来自B站up秋葉aaaki&#xff0c;近期发布了Stable Diffusion整合包v4版本&#xff0c;一键在本地部署S…

划分子网和构造超网的学习

子网掩码长度&#xff1d;32位 某位&#xff1d;1&#xff1a;IP地址中的对应位为网络号和子网号 某位&#xff1d;0&#xff1a;IP地址中的对应位为主机号 从一个 IP 数据报的首部并无法判断源主机或目的主机所连接的网络是否进行了子网划分。 使用子网掩码(subnet mask)可…

leetcode第709题:转换成小写字母

注意字符不仅有26个英文字母&#xff0c;还有特殊字符。特殊字符的话&#xff0c;原样输出。 public class Solution {public char toLowChar(char c){if(c>a&&c<z){return c;}else if(c>A&&c<Z){int n(int)c32;return (char)n;}return c;}publi…

cuda thread和block值怎么配置(个人经验)

1.查询自己的GPU算力&#xff1b; 2.对应算力查找资源限制&#xff1b; 详见CUDA_C_Programming_Guide.pdf&#xff0c;Chapter 19. Compute Capabilities 3.例如算力8.7&#xff0c;关注以下几个值&#xff1a; warp size32&#xff1b; Maximum number of resident warps…

注意力机制新突破!21种创新融合思路汇总!让技术持续飞跃!

CV和注意力机制都是当下深度学习中不可或缺的技术&#xff0c;而【CV注意力机制】更是当前学术研究的热点领域之一&#xff0c;这种结合的方法可以使得注意力机制使模型能够捕捉到图像中的关键信息&#xff0c;从而提供更丰富的特征表示&#xff0c;这对于图像分类、目标检测和…

Centos7 调整分区大小

在安装完centos系统以后&#xff0c;系统的分区大小往往不是自己预期的大小&#xff0c;这个时候就需要我们自己手动来调整分区大小&#xff0c;在centos7 里面&#xff0c;手动调整分区大小的方法如下 1、查看目前分区的情况 从上面的查询结果我们可以看出&#xff0c;根目录…

护眼灯是不是智商税?带你轻松了解选择护眼台灯的标准

在当今时代&#xff0c;我们观察到一个不容忽视的现象&#xff1a;孩子们的视力问题日益增多&#xff0c;这无疑向众多家长发出了警示。它提醒着我们&#xff0c;除了追求学术成就之外&#xff0c;孩子们的视觉健康同样重要&#xff0c;不容忽视。因此&#xff0c;选择一款适合…

刷代码随想录有感(108):动态规划——目标和

题干&#xff1a; 代码&#xff1a; class Solution { public:int findTargetSumWays(vector<int>& nums, int target) {int sum 0;for(int i : nums) sum i;if(abs(target) > sum)return 0;if((sum target) % 2 ! 0)return 0;int bagweight (sum target) /…

qmt量化交易策略小白学习笔记第37期【qmt编程之指数数据--如何获取迅投商品市场指数行情数据】

qmt编程之获取商品市场指数数据 qmt更加详细的教程方法&#xff0c;会持续慢慢梳理。 也可找寻博主的历史文章&#xff0c;搜索关键词查看解决方案 &#xff01; 感谢关注&#xff0c;咨询免费开通量化回测与获取实盘权限&#xff0c;欢迎和博主联系&#xff01; 获取迅投商…

yolov8划线计数脚本-可用于统计人流车流

支持自定义线的位置&#xff1b; 支持使用自己训练的模型和检测类别&#xff1b; "YOLOv8划线计数脚本" 是一个基于YOLOv8&#xff08;You Only Look Once version 8&#xff09;对象检测模型的计算机视觉应用项目&#xff0c;主要用于实现人流和车流的自动统计。该…

【GD32F303红枫派使用手册】第十八节 USART-485通信实验

18.1 实验内容 通过本实验主要学习以下内容&#xff1a; 485工作原理 串口单线工作原理 18.2 实验原理 18.2.1 485工作原理 485一般指RS485。RS485名TIA-485-A, ANSI/TIA/EIA-485或TIA/EIA-485&#xff0c;是由电信业协会和电业联盟定义。RS485就是个硬件通信协议&#x…

Zabbix自定义监控JAVA进程

一.定义脚本 二 .ZABBIX得agent允许以root身份执行 三. Zabbix测试自定item是否成功 四.ZABBIX服务端web添加新得item项 五.查看最新数据&#xff0c;取值成功

Erlang程序设计[Part2 chapter5-chapter8]

两种数据容器&#xff1a;元组、列表 part 2 chapter5 记录与映射组 记录 记录其实就是元组的另一种形式。通过使用记录&#xff0c;可以给元组里的各个元素关联一个名称。 映射 映射组是键 值对的关联性集合。 通过记录命名元组里的项 记录的产生背景&#xff1a; 对于小型元…

反射的原理和操作

反射是框架设计的灵魂 &#xff08;使用的前提条件&#xff1a;必须先得到代表的字节码的Class&#xff0c;Class类用于表示.class文件&#xff08;字节码&#xff09;&#xff09; 在Java中&#xff0c;反射是指在运行时动态地获取、检查和操作类、对象、方法和属性的能力。J…

本地部署AI模型-phi3

What&#xff1a; Phi-3-Mini被认为是Microsoft计划发布的三款小型机型中的首款。据报道&#xff0c;在语言、推理、编码和数学等领域&#xff0c;它在各种基准测试中的表现优于相同大小和下一个尺寸的模型。 从本质上讲&#xff0c;语言模型是 ChatGPT、Claude、Gemini 等 AI…

各类存储器类型(RAM、ROM、FLASH、DRAM、SRAM)

1 计算机存储类型构成 在计算机中&#xff0c;各类存储器构成了计算机能高速高效运转程序的基石。 计算机的存储体系中&#xff0c;从速度慢到速度快对应着容量大到小&#xff0c;也就是说&#xff0c;速度越快容量越小&#xff1b;容量越大的&#xff0c;速度越慢。两者互相…