React Native 全栈开发实战班 - 数据管理与状态之Zustand应用

在 React Native 应用中,状态管理 是构建复杂用户界面的关键。随着应用规模的增长,组件之间的数据共享和状态同步变得越来越复杂。虽然 React 提供了 Context API 作为内置的状态管理解决方案,但在大型应用中,使用更强大的状态管理库可以提高代码的可维护性和可扩展性。

Zustand 是一个轻量级、简单易用的状态管理库,基于 React Hooks 构建。它提供了类似于 Redux 的功能,但使用起来更加简洁和直观。本章节将介绍 Zustand 的基本概念、安装步骤、基本用法以及在 React Native 项目中的应用示例。


4.1 Zustand 简介

Zustand 是一个由 Poimandres 团队开发的轻量级状态管理库,旨在提供一种简单的方式来管理 React 应用的状态。与 Redux 相比,Zustand 更加简洁,不需要编写大量的样板代码,并且与 React Hooks 完美集成。

Zustand 的主要特点:

  • 简单易用: 基于 React Hooks,API 简洁直观。
  • 高性能: 使用 Proxy 实现细粒度的状态更新,避免不必要的重新渲染。
  • 可扩展性: 支持中间件和插件,可以轻松扩展功能。
  • 轻量级: 体积小,适合中小型应用。

4.2 安装 Zustand

首先,需要安装 Zustand 及其依赖包。

npm install zustand

4.3 基本用法
4.3.1 创建 Store

使用 create 函数创建一个 Store,Store 是一个包含状态和更新状态方法的 JavaScript 对象。

示例:

// store.js
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 函数接收一个函数作为参数,该函数返回一个对象,包含初始状态和更新状态的方法。
  • set 函数用于更新状态,接收一个函数,该函数接收当前状态并返回新的状态。
4.3.2 在组件中使用 Store

使用 useStore Hook 在组件中访问和更新状态。

示例:

// Counter.js
import React from 'react';
import { View, Text, Button, StyleSheet } from 'react-native';
import useStore from './store';const Counter = () => {const count = useStore((state) => state.count);const increment = useStore((state) => state.increment);const decrement = useStore((state) => state.decrement);return (<View style={styles.container}><Text style={styles.text}>Count: {count}</Text><Button title="Increment" onPress={increment} /><Button title="Decrement" onPress={decrement} /></View>);
};const styles = StyleSheet.create({container: {flex: 1,justifyContent: 'center',alignItems: 'center',},text: {fontSize: 18,marginBottom: 10,},
});export default Counter;

解释:

  • useStore Hook 可以接收一个 selector 函数,用于选择需要的状态。
  • incrementdecrement 是更新状态的方法。
4.3.3 异步数据获取

Zustand 支持异步操作,可以直接在 Store 中处理异步数据获取。

示例:

// store.js
import create from 'zustand';const useStore = create((set) => ({data: null,fetchData: async () => {const response = await fetch('https://example.com/api/data');const json = await response.json();set({ data: json });},
}));export default useStore;
// DataFetcher.js
import React from 'react';
import { View, Text, Button, StyleSheet } from 'react-native';
import useStore from './store';const DataFetcher = () => {const data = useStore((state) => state.data);const fetchData = useStore((state) => state.fetchData);return (<View style={styles.container}>{data ? (<Text style={styles.text}>{JSON.stringify(data)}</Text>) : (<Button title="Fetch Data" onPress={fetchData} />)}</View>);
};const styles = StyleSheet.create({container: {flex: 1,justifyContent: 'center',alignItems: 'center',},text: {fontSize: 16,},
});export default DataFetcher;

解释:

  • fetchData 方法是一个异步函数,用于获取数据并更新 Store。
  • 在组件中调用 fetchData 方法即可触发数据获取。

4.4 中间件与插件

Zustand 支持中间件和插件,可以扩展 Store 的功能。例如,可以使用 immer 中间件来简化状态更新逻辑。

示例:

// store.js
import create from 'zustand';
import immer from 'zustand/middleware/immer';const useStore = create(immer((set) => ({user: { name: '张三', age: 30 },updateUser: (update) => set((state) => {state.user = { ...state.user, ...update };}),}))
);export default useStore;
// UserUpdater.js
import React from 'react';
import { View, Text, Button, StyleSheet } from 'react-native';
import useStore from './store';const UserUpdater = () => {const updateUser = useStore((state) => state.updateUser);return (<View style={styles.container}><Buttontitle="Update User"onPress={() => updateUser({ age: 31 })}/></View>);
};const styles = StyleSheet.create({container: {marginTop: 20,padding: 10,backgroundColor: '#f0f0f0',borderRadius: 5,},
});export default UserUpdater;

解释:

  • 使用 immer 中间件,可以直接修改状态对象,而无需手动返回新对象。
  • updateUser 方法接收一个对象,用于更新用户信息。

4.5 综合示例

以下是一个使用 Zustand 实现计数器功能的完整示例。

// store.js
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;
// Counter.js
import React from 'react';
import { View, Text, Button, StyleSheet } from 'react-native';
import useStore from './store';const Counter = () => {const count = useStore((state) => state.count);const increment = useStore((state) => state.increment);const decrement = useStore((state) => state.decrement);return (<View style={styles.container}><Text style={styles.text}>Count: {count}</Text><Button title="Increment" onPress={increment} /><Button title="Decrement" onPress={decrement} /></View>);
};const styles = StyleSheet.create({container: {flex: 1,justifyContent: 'center',alignItems: 'center',},text: {fontSize: 18,marginBottom: 10,},
});export default Counter;
// App.js
import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import Counter from './Counter';
import DataFetcher from './DataFetcher';const Stack = createNativeStackNavigator();const App = () => {return (<NavigationContainer><Stack.Navigator initialRouteName="Counter"><Stack.Screen name="Counter" component={Counter} /><Stack.Screen name="DataFetcher" component={DataFetcher} /></Stack.Navigator></NavigationContainer>);
};export default App;

总结

本章节介绍了 Zustand 的基本概念、安装步骤、基本用法以及在 React Native 项目中的应用示例。Zustand 是一种轻量级、简单易用的状态管理解决方案,适合中小型应用或特定场景下的状态管理。通过 Zustand,开发者可以更高效地管理应用状态,提高代码的可维护性和可扩展性。


课后作业

  1. 使用 Zustand 实现一个简单的计数器应用。
  2. 创建一个包含异步数据获取的应用,使用 Zustand 管理数据状态。
  3. 阅读 Zustand 官方文档,深入了解 Zustand 的高级用法和插件。

导师简介

前腾讯电子签的前端负责人,现 whentimes tech CTO,专注于前端技术的大咖一枚!一路走来,从小屏到大屏,从 Web 到移动,什么前端难题都见过。热衷于用技术打磨产品,带领团队把复杂的事情做到极简,体验做到极致。喜欢探索新技术,也爱分享一些实战经验,帮助大家少走弯路!

温馨提示:可搜老码小张公号联系导师

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

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

相关文章

Nginx 使用入门介绍

大家好&#xff0c;我是G探险者&#xff01; 今天聊一聊nginx. Nginx 是一款高性能的 Web 服务器、反向代理服务器以及负载均衡器。它因其轻量级、稳定性和高并发处理能力&#xff0c;在全球范围内得到了广泛应用。许多大型网站&#xff08;如 Netflix、Dropbox 和 WordPress…

Elasticsearch 重建索引 数据迁移

Elasticsearch 重建索引 数据迁移 处理流程创建临时索引数据迁移重建索引写在最后 大家都知道&#xff0c;es的索引创建完成之后就不可以再修改了&#xff0c;包括你想更改字段属性或者是分词方式等。那么随着业务数据量的发展&#xff0c;可能会出现需要修改索引&#xff0c;或…

vue3 路由写法及传参方式 !超详细

Vue Router 是 Vue.js 官方的路由管理器。它主要用于单页面应用程序&#xff08;SPA, Single Page Application&#xff09;中&#xff0c;帮助解决页面导航、组件复用等问题。 基本的使用 1.router配置文件代码 创建一个ts文件,用来写路由器 // 创建一个路由器,并暴露出去 …

有限状态机(续)

一、添加刀光和场景 1、资源链接&#xff1a; 武器刀光&#xff1a;https://assetstore.unity.com/packages/tools/particles-effects/melee-weapon-trail-1728 场景&#xff1a;https://assetstore.unity.com/packages/3d/environments/fantasy/casual-tiny-environment-ju…

内网安全隧道搭建-ngrok-frp-nps-sapp

1.ngrok 建立内网主机与公网跳板机的连接&#xff1a; 内网主机为客户机&#xff1a; 下载客户端执行 2.frp

模电数电,融会贯通

模电与数电在传统电子工程中似乎被划分为两大领域&#xff0c;然而&#xff0c;它们实际上是对同一器件的不同应用方法。这种观念有助于我们理解元器件在各种工作状态下的多样性&#xff0c;并在复杂的电路设计中实现更高效的系统集成。 一、三极管的多重身份&#xff1a;放大…

鸿蒙动画开发07——粒子动画

1、概 述 粒子动画是在一定范围内随机生成的大量粒子产生运动而组成的动画。 动画元素是一个个粒子&#xff0c;这些粒子可以是圆点、图片。我们可以通过对粒子在颜色、透明度、大小、速度、加速度、自旋角度等维度变化做动画&#xff0c;来营造一种氛围感&#xff0c;比如下…

Java——并发工具类库线程安全问题

摘要 本文探讨了Java并发工具类库中的线程安全问题&#xff0c;特别是ThreadLocal导致的用户信息错乱异常场景。文章通过一个Spring Boot Web应用程序示例&#xff0c;展示了在Tomcat线程池环境下&#xff0c;ThreadLocal如何因线程重用而导致异常&#xff0c;并讨论了其他并发…

PostgreSQL技术内幕18:物理备份工具pg_basebackup

0.简介 PG自带备份工具有多种&#xff0c;pg_basebackup、pg_dump、pg_dumpall&#xff0c;其中pg_basebackup是文件系统级别的备份&#xff0c;其余两种是逻辑备份。本文主要介绍PG备份工具产生的背景和概念&#xff0c;以及对pg_basebackup使用方法和其实现原理进行详细说明…

基于Python实现的HDR图像处理算法

此代码会读取两张图片&#xff0c;一张用于保留高光细节&#xff0c;另一张用于保留暗部细节。两张图片按指定比例进行像素融合&#xff0c;最终生成一张合成的HDR图片。 import cv2 import numpy as npdef hdr_fusion(highlight_img_path, shadow_img_path, output_path, alp…

计算机网络-理论部分(二):应用层

网络应用体系结构 Client-Server客户-服务器体系结构&#xff1a;如Web&#xff0c;FTP&#xff0c;Telnet等Peer-Peer&#xff1a;点对点P2P结构&#xff0c;如BitTorrent 应用层协议定义了&#xff1a; 交换的报文类型&#xff0c;请求or响应报文类型的语法字段的含义如何…

【JavaEE初阶 — 多线程】wait() notify()

1. 协调多个线程之间的执行先后顺序的方法介绍 由于线程之间是抢占式执行的&#xff0c;因此线程之间执行的先后顺序难以预知&#xff1b;但是实际开发中&#xff0c;有时候我们希望合理地协调多个线程之间的执行先后顺序。 拓展&#xff1a; wait() 和 sleep() 的区别 …

Vscode/Code-server无网环境安装通义灵码

Date: 2024-11-18 参考材料&#xff1a;https://help.aliyun.com/zh/lingma/user-guide/individual-edition-login-tongyi-lingma?spma2c4g.11186623.0.i0 1. 首先在vscode/code-server插件市场中安装通义插件&#xff0c;这步就不细说了。如果服务器没网&#xff0c;会问你要…

Java项目实战II基于Java+Spring Boot+MySQL的共享汽车管理系统(源码+数据库+文档)

目录 一、前言 二、技术介绍 三、系统实现 四、文档参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发&#xff0c;CSDN平台Java领域新星创作者&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末 一、前言 在共享经济…

美赛优秀论文阅读--2023C题

文章目录 1.题目说明2.我对于这个题目信息的理解3.优秀论文学习3.1摘要3.2相关的算法模型 4.总结 1.题目说明 今天阅读的这个文章来自于这个2023年的这个美赛的这个C题的论文&#xff1b; 我们的这个题目可以到网上去找&#xff0c;这个还是比较容易找到的&#xff0c;大致就…

ChromeDriver驱动下载地址更新(保持最新最全)

说明&#xff1a; ChromeDriver 是 Selenium WebDriver 用于控制 Chrome 的独立可执行文件。 为了方便下载使用&#xff0c;本文保持ChromeDriver的最新版本更新&#xff0c;并提供115.0.5763.0-133.0.6841.0版本的下载地址&#xff1a; 所有版本和下载地址&#xff1a; &am…

delphi fmx android 离线人脸识别

搜遍全网都没有找到delphi android 能用的 离线人脸识别,无需注册什么开发者 有这方面需求的可以用fsdk 这边用的luxand.FSDK8.0 android下的注册号要自己找下 1,用老猫的工具将android 下的sdk,FSDK.java 编译成FSDK.jar 老猫的工具 2,用上面的工具将FSDK.jar 生成de…

【模块一】kubernetes容器编排进阶实战资源对象之Configmap与Secret简介

kubernetes 资源对象详解及示例 kubernetes 的几个重要概念 资源对象&#xff1a;kubernetes基于声明式API&#xff0c;和资源对象进行交互。 yaml文件&#xff1a;为了方便后期管理&#xff0c;通过使用yaml文件通过API管理资源对象。 yaml必需字段&#xff1a; apiVersio…

游戏引擎学习第14天

视频参考:https://www.bilibili.com/video/BV1iNUeYEEj4/ 1. 为什么关注内存管理&#xff1f; 内存分配是潜在的失败点&#xff1a; 每次进行内存分配&#xff08;malloc、new等&#xff09;时&#xff0c;都可能失败&#xff08;例如内存不足&#xff09;。这种失败会引入不稳…

游戏引擎学习第12天

视频参考:https://www.bilibili.com/video/BV1yom9YnEWY 这节没讲什么东西&#xff0c;主要是改了一下音频的代码 后面有介绍一些alloc 和malloc,VirtualAlloc 的东西 _alloca 函数&#xff08;或 alloca&#xff09;分配的是栈内存&#xff0c;它的特点是&#xff1a; 生命周…