十五、redis的使用

news2024/12/25 17:14:12

目录

  • 一、简介
    • 1.1 nosql介绍
    • 1.2 redis特性
    • 1.3 redis优势
    • 1.4 redis应用场景
  • 二、安装
    • 2.1 Macos下安装
    • 2.2 Linux下安装
    • 2.4 客户端连接
    • 2.5 切换数据库
  • 三、数据库操作
    • 3.1 string类型
    • 3.2 键的操作
    • 3.3 Hash类型
    • 3.4 list类型
    • 3.5 set类型
    • 3.6 zset类型
  • 四、和python交互
    • 4.1 安装redis包
    • 4.2 string方法操作
    • 4.3 在django使用redis

一、简介

  • Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。从2010年3月15日起,Redis的开发工作由VMware主持。从2013年5月开始,Redis的开发由Pivotal赞助。
  • Redis是 NoSQL技术阵营中的一员,它通过多种键值数据类型来适应不同场景下的存储需求,借助一些高层级的接口使用其可以胜任,如缓存、队列系统的不同角色
  • 官网介绍

1.1 nosql介绍

一类新出现的数据库(not only sql),它的特点有:

  • 不支持SQL语法
  • 不支持事务
  • 存储结构跟传统关系型数据库中的那种关系表完全不同,nosql中存储的数据都是KV形式
  • NoSQL的世界中没有一种通用的语言,每种nosql数据库都有自己的api和语法,以及擅长的业务场景
  • NoSQL中的产品种类相当多:
    • Mongodb
    • Redis
    • Hbase hadoop
    • Cassandra hadoop

1.2 redis特性

Redis 与其他 key - value 缓存产品有以下三个特点:

  • Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
  • Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
  • Redis支持数据的备份,即master-slave模式的数据备份。

1.3 redis优势

  • 性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。
  • 丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。
  • 原子 – Redis的所有操作都是原子性的,同时Redis还支持对几个操作全并后的原子性执行。
  • 丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。

1.4 redis应用场景

  • 用来做缓存(ehcache/memcached)——redis的所有数据是放在内存中的(内存数据库)
  • 可以在某些特定应用场景下替代传统数据库——比如社交类的应用
  • 在一些大型系统中,巧妙地实现一些特定的功能:session共享、购物车

二、安装

2.1 Macos下安装

(1) 通过brew去安装

brew install redis

在这里插入图片描述
安装路径位于

/opt/homebrew/opt/redis

在这里插入图片描述
(2) 在前台启动和停止 Redis
要测试 Redis 安装,可以运行下面命令:

redis-server

如果成功,您将看到 Redis 的启动日志,Redis 将在前台运行。
在这里插入图片描述
可以看到这种启动方式, 终端会一直工作, 要停止 Redis,输入 Ctrl-C 。
(3) 在后台启动和停止 Redis
通过 launchd 后台启动, 命令如下:

brew services start redis

在这里插入图片描述
这将启动 Redis 并在登录时重新启动它。您可以通过运行以下命令来检查 launchd 托管 Redis 的状态:

brew services info redis

在这里插入图片描述
要停止该服务,运行如下命令:

brew services stop redis

2.2 Linux下安装

(1) 下载源文件

wget https://download.redis.io/redis-stable.tar.gz

(2) 解压/复制

tar -zxvf redis-stable.tar.gz
sudo mv ./redis-stable /usr/local/redis/

(3) 编译安装

cd /usr/local/redis/
sudo make
sudo make test
sudo make install

(4) 查看安装文件

cd /usr/local/bin
ls -all

在这里插入图片描述

- redis-server: redis服务器
- redis-cli: redis命令行客户端
- redis-benchmark: redis性能测试工具
- redis-check-aof: AOF文件修复工具
- redis-check-rdb: RDB文件检索工具

(5) 移动配置文件

sudo cp /usr/local/redis/redis.conf /etc/redis/

2.3 个性化配置
Macos的配置文件位于:

/opt/homebrew/etc/redis.conf

Linux的配置文件位于:

/etc/redis/redis.conf

(1) 绑定ip
如果需要远程访问,可将此⾏注释,或绑定⼀个真实ip, 默认是配置了本机地址
在这里插入图片描述
(2) 端⼝,默认为6379
在这里插入图片描述
(3) 是否以守护进程运⾏

  • 如果以守护进程运⾏,则不会在命令⾏阻塞,类似于服务
  • 如果以⾮守护进程运⾏,则当前终端被阻塞
  • 设置为yes表示守护进程,设置为no表示⾮守护进程
  • 推荐设置为yes

在这里插入图片描述
(4) 数据库文件
在这里插入图片描述
(5) 数据⽂件存储路径
在这里插入图片描述
(6) 配置日志文件
需要提前创建目录和文件在这里插入图片描述
(7) 默认数据库的个数
在这里插入图片描述

2.4 客户端连接

客户端连接的命令为

redis-cli

通过–help可以查看帮助选项
在这里插入图片描述
连接本机可以不需要指定-h和-p, 连接本机成功展示如下:
在这里插入图片描述
此时输入ping会返回pong
在这里插入图片描述

2.5 切换数据库

数据库没有名称,默认有16个,通过0-15来标识,连接redis默认选择第一个数据库
通过select n可以切换数据库, 其中n为0~15, 如下所示:
在这里插入图片描述

三、数据库操作

Redis支持以下5种主要的数据类型:

  • 字符串(String):最基本的数据类型,可以存储字符串、整数或浮点数。
  • 列表(List):有序的字符串列表,可以在列表的头部或尾部进行元素的插入、删除和获取。
  • 哈希(Hash):键值对的集合,适合存储对象的属性和值。
  • 集合(Set):无序的字符串集合,不允许重复的元素。
  • 有序集合(Sorted Set):类似于集合,每个元素都关联一个分数,可以根据分数进行排序,并且每个元素的分数必须是唯一的。

3.1 string类型

字符串类型是Redis中最为基础的数据存储类型,它在Redis中是二进制安全的,这便意味着该类型可以接受任何格式的数据,如JPEG图像数据或Json对象描述信息等。在Redis中字符串类型的Value最多可以容纳的数据长度是512M。
(1) 保存值
如果设置的键不存在则为添加,如果设置的键已经存在则修改

set key value

例如:
在这里插入图片描述
(2) 设置键值及过期时间,以秒为单位

setex key second value

例如:
在这里插入图片描述
(3) 设置多个键值
mset key1 value1 [key2 value2 …]
在这里插入图片描述
(4) 追加值
append key value
在这里插入图片描述
(5) 获取单个值

get key

(6) 根据多个键获取多个值

mget key1 key2 ...

在这里插入图片描述

3.2 键的操作

(1) 搜索键, 支持正则表达式

keys pattern

在这里插入图片描述
通配符*表示所有.

(2) 判断键是否存在

exists key1

在这里插入图片描述
存在返回1, 不存在返回0
(3) 查看键对应的value的类型

type key

在这里插入图片描述
(4) 删除键

del key1 key2 ...

在这里插入图片描述
(5) 设置过期时间,以秒为单位

expire key seconds

在这里插入图片描述
返回结果 (integer) 1 表示命令执行成功,且设置过期时间成功。

(6) 查看有效时间,以秒为单位
ttl key
返回结果 (integer) -2 表示该键不存在或已过期。具体含义如下:

  • -1 表示键存在但没有设置过期时间。
  • -2 表示键不存在或已过期。
  • 其他正整数表示键的剩余生存时间(以秒为单位)。
    在这里插入图片描述
    过期后, 这个键值对会删除掉.

3.3 Hash类型

  • hash⽤于存储对象,对象的结构为属性、值
  • 值的类型为string
    (1) 增加、修改
    设置单个属性
hset key field value [field value...]

在这里插入图片描述
(2) 获取指定键所有的属性名

hkeys key

在这里插入图片描述
(3) 获取⼀个属性的值

hget key field

在这里插入图片描述
(4) 获取多个属性的值

hmget  key field [field...]

在这里插入图片描述
(5) 获取所有属性的值

hvals key

在这里插入图片描述
(6) 删除操作
删除整个hash键及值,使⽤del命令
删除属性,属性对应的值会被⼀起删除

hdel key field1 field2 ...

在这里插入图片描述

3.4 list类型

  • 列表的元素类型为string
  • 按照插⼊顺序排序
    (1) 添加
    在左侧插⼊数据
lpush key value1 value2 ...

在这里插入图片描述
在右侧插⼊数据

rpush key value1 value2 ...

在这里插入图片描述
(2) 在指定元素的前或后插⼊新元素
linsert key before或after 现有元素 新元素
在这里插入图片描述
(3) 获取元素
返回列表⾥指定范围内的元素
lrarge key start stop

  • start、stop为元素的下标索引
  • 索引从左侧开始,第⼀个元素为0
  • 索引可以是负数,表示从尾部开始计数,如-1表示最后⼀个元素
    在这里插入图片描述
    (4) 设置指定索引位置的元素值
    lset key index value
  • 索引从左侧开始,第⼀个元素为0
  • 索引可以是负数,表示尾部开始计数,如-1表示最后⼀个元素
    在这里插入图片描述
    (5) 删除指定元素
    lrem key count value
  • 将列表中前count次出现的值为value的元素移除
  • count > 0: 从头往尾移除
  • count < 0: 从尾往头移除
  • count = 0: 移除所有

3.5 set类型

  • ⽆序集合
  • 元素为string类型
  • 元素具有唯⼀性,不重复
  • 说明:对于集合没有修改操作
    (1) 添加元素
sadd key member1 member2 ...

在这里插入图片描述
(2) 获取所有元素

smembers key

在这里插入图片描述
(3) 删除指定元素

srem key member [member...]

在这里插入图片描述
在这里插入图片描述

3.6 zset类型

  • sorted set,有序集合
  • 元素为string类型
  • 元素具有唯⼀性,不重复
  • 每个元素都会关联⼀个double类型的score,表示权重,通过权重将元素从⼩到⼤排序
  • 没有修改操作
    (1) 增加
zadd key score1 member1 score2 member2 ..

例如向键’a4’的集合中添加元素’lisi’、‘wangwu’、‘zhaoliu’、‘zhangsan’,权重(score)分别为4、5、6、3
在这里插入图片描述

(2) 获取

zrange key start stop
  • 返回指定范围内的元素
  • start、stop为元素的下标索引
  • 索引从左侧开始,第⼀个元素为0
  • 索引可以是负数,表示从尾部开始计数,如-1表示最后⼀个元素
    在这里插入图片描述
    (3) 返回score值在min和max之间的成员
zrangebyscore key min max

在这里插入图片描述
(4) 返回成员member的score值
在这里插入图片描述
(5) 删除

zrem key member1 member2 ...

删除集合’a4’中元素’zhangsan’
在这里插入图片描述
删除权重在指定范围的元素

zremrangebyscore key minindex maxindex

在这里插入图片描述

四、和python交互

4.1 安装redis包

进入虚拟环境中安装

mkvirtualenv -p python3 redis_study
workon redis_study
pip install redis

使用pycharm创建项目
在这里插入图片描述
创建StrictRedis对象

from redis import *

if __name__ == "__main__":
    try:
        # 创建StrictRedis对象,与redis服务器建⽴连接
        # 通过init创建对象,指定参数host、port与指定的服务器和端⼝连接,host默认为localhost,port默认为6379,db默认为0
        sr = StrictRedis(host='localhost', port=6379, db=0)
        # 简写
        # sr=StrictRedis()
    except Exception as e:
        print(e)

根据不同的类型,拥有不同的实例⽅法可以调⽤,与前⾯学的redis命令对应,⽅法需要的参数与命令的参数⼀致

4.2 string方法操作

(1) set操作
⽅法set,添加键、值,如果添加成功则返回True,如果添加失败则返回False
注意: Redis中存储的数据都是二进制的,所以存储的对象都是字节串, 字节串前是有一个b来区分的

if __name__ == "__main__":
    try:
        sr = StrictRedis()
        result = sr.set('name', '张三2')
        # 输出响应结果,如果添加成功则返回True,否则返回False
        print(result)
    except Exception as e:
        print(e)

(2) string获取
⽅法get,添加键对应的值,如果键存在则返回对应的值,如果键不存在则返回None

if __name__ == "__main__":
    try:
        sr = StrictRedis()
        # 获取键name的值
        result = sr.get('name')
        # 有中文的话需要解码
        decoded_result = result.decode('utf-8')
        print(result)
        print(decoded_result)
    except Exception as e:
        print(e)

输出结果:

b'\xe5\xbc\xa0\xe4\xb8\x892'
张三2

(3) string修改
⽅法set,如果键已经存在则进⾏修改,如果键不存在则进⾏添加

from redis import *

if __name__ == "__main__":
    try:
        sr = StrictRedis()
        # 获取键name的值
        sr.set('name', 'zhangsan')
        result = sr.get('name').decode('utf-8')
        print(f"修改前{result}")
        sr.set('name', 'lisi')
        result = sr.get('name').decode('utf-8')
        print(f"修改后{result}")
    except Exception as e:
        print(e)

输出结果:

修改前zhangsan
修改后lisi

(4) string删除
⽅法delete,删除键及对应的值,如果删除成功则返回受影响的键数,否则则返 回0

from redis import *

if __name__ == "__main__":
    try:
        sr = StrictRedis()
        # 获取键name的值
        sr.set('name', 'zhangsan')
        sr.delete('name')
        result = sr.get('name')
        print(f"删除后{result}")
    except Exception as e:
        print(e)

结果:

删除后None

(5) 获取键
⽅法keys,根据正则表达式获取键

from redis import *

if __name__ == "__main__":
    try:
        sr = StrictRedis()
        # 获取所有的键
        result = sr.keys()
        # 输出响应结果,所有的键构成⼀个列表,如果没有键则返回空列表
        print(result)
    except Exception as e:
        print(e)

输出结果:

[b'hobby', b'user', b'arr1']

4.3 在django使用redis

之前django的session默认是存在的数据库里面的,我们也可以把session存储在redis里面
(1) 创建django项目

 workon redis_study 
 pip install django
 pip install redis
 cd workspace/python/redis_study
 django-admin startproject session_test

(2) 修改settings文件,增加如下项

SESSION_ENGINE = 'redis_sessions.session'
SESSION_REDIS = {
    'host': 'localhost',
    'port': 6379,
    'db': 2, # 选择3个数据库
    'password': '',
    'prefix': 'session',
    'socket_timeout': 1
}
SESSION_COOKIE_AGE = 3600  # Session过期时间,单位为秒

其中,SESSION_ENGINE指定使用redis_sessions.session作为Session存储引擎。
SESSION_REDIS指定了Redis的连接配置,其中包括主机、端口、数据库、密码等信息。prefix参数指定了存储在Redis中的Session键的前缀,可以根据需要自行设置。
SESSION_COOKIE_AGE指定了Session的过期时间,单位为秒。具体的配置可以根据实际需求进行调整。

(3) 添加应用

cd session_test 
python manage.py startapp booktest

(4) 修改setting文件添加booktest和redis应用


INSTALLED_APPS = [
    ...
    'booktest',
    'redis'
]

(5) 配置项目的url文件
将booktest应用的url配置加到映射中

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    # 添加映射, 将booktest/路径 和 booktest.urls.py进行关联
    path('booktest/', include('booktest.urls')),
]

(6) 测试
打开booktest/views.py文件,创建session_set和session_get视图如下

from django.http import HttpResponse


# 保存session
def session_set(request):
    request.session['name'] = '张三'
    return HttpResponse('ok')

# 获取session
def session_get(request):
    name = request.session['name']
    return HttpResponse(name)

添加booktest/urls.py文件,配置url如下

from django.contrib import admin
from django.urls import path, include

from booktest import views

urlpatterns = [
    path('session_set/', views.session_set, name='session_set'),
    path('session_get/', views.session_get, name='session_get'),
]

(7) 启动项目

python manage.py runserver

输入地址:http://127.0.0.1:8000/booktest/session_set/ 进行session存储
输入地址http://127.0.0.1:8000/booktest/session_get/ 获取session值
然后通过redis-cli客户端查看
在这里插入图片描述
查看对应的value
在这里插入图片描述
Base64在线解码https://base64.us/
在这里插入图片描述
其中\u5f20\u4e09对应的中文就是张三
在这里插入图片描述

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

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

相关文章

3.2每日一题(定积分求抽水做工问题)

1、画图&#xff0c;把题目的容器画出来&#xff1a;球形容器&#xff0c;半径为R 2、根据容器的形状进行分析&#xff1a; 抽水的实质是不同深度的水抽出去走的位移是不一样的>抽水的过程 &#xff1a; &#xff08;1&#xff09;先考虑深度为 x到xdx 的薄层水抽出去做多少…

草料资料库丨2023年全国消防宣传月资料合集,免费下载

2023年11月9日是第32个全国消防日&#xff0c;国务院安委会办公室决定于11月份在全国开展消防宣传月活动&#xff0c;主题是“预防为主&#xff0c;生命至上”。 结合今年消防安全月相关要求&#xff0c;我们特邀 注册安全工程师 邵悦 为大家整理了2023年全国消防宣传月的资料…

2023-在mac下安装Homebrew的国内镜像

mac安装Homebrew的国内镜像 尝试使用其他下载源&#xff1a;GitHub 可能会受到访问限制&#xff0c;尝试使用其他镜像或下载源。您可以使用清华大学、中科大或阿里云的 Homebrew 镜像&#xff0c;以提高下载速度和可靠性。例如&#xff0c;可以使用阿里云的镜像来安装 Homebre…

myCobot 320 APP 控制技术案例

引言 机械臂是现代工业和科研领域中的重要工具&#xff0c;它们在制造业、医疗、农业、教育等多个领域都有广泛的应用。这些机器臂不仅可以进行精密操作&#xff0c;而且能够在人类无法进入的危险环境中工作&#xff0c;大大提高了工作效率和安全性。然而&#xff0c;传统的机械…

UE5 日记(人物连招:蒙太奇动画通知(含视频链接))

教程https://www.youtube.com/watch?vsWpENaVGj2M&listPLiSlOaRBfgkcPAhYpGps16PT_9f28amXi&index10&ppiAQB 相关蓝图 连招逻辑 动画通知类 逻辑分析 1.用户输入 已搭载战斗系统模块,可以收到输入指令 2.连击 第一次攻击&#xff1a; 第一次攻击&#xff0c;…

camtasia studio 2024功能介绍安装教程

Camtasia studio 2024是一款功能强大的屏幕录制和视频编辑软件。它可以帮助用户轻松地记录电脑屏幕上的任何操作&#xff0c;并可以将录制的视频进行编辑和制作成高质量的视频教程、演示文稿、培训课程等。 Camtasia studio 2024具有直观的界面和易于使用的工具&#xff0c;包…

springboot动态数据源【非伪数据源】

说明&#xff1a;本文章的数据源不是在配置文件中配置两个或多个数据源&#xff0c;在业务方面对这些数据源来回切换&#xff0c;本文章中的数据源是可以动态添加&#xff0c;修改&#xff0c;切换的&#xff0c;废话不多说。 先看工程图&#xff1a; 1.pom.xml文件 <?x…

第五章 I/O管理 三、I/O控制方式(程序直接控制、中断驱动方式、DMA方式、通道控制方式)

目录 一、程序直接控制方式 1、以读操作为例 2、CPU的干预 3、数据传送的单位 4、数据的流向 5、优点 6、缺点 二、中断驱动方式 1、定义&#xff1a; 2、CPU干预的频率 3、数据传送的单位 4、数据的流向 5、主要缺点和主要优点 优点: 缺点: 三、DMA方式&#x…

R语言使用surveyCV包对NHANES数据(复杂调查加权数据)进行10折交叉验证

美国国家健康与营养调查&#xff08; NHANES, National Health and Nutrition Examination Survey&#xff09;是一项基于人群的横断面调查&#xff0c;旨在收集有关美国家庭人口健康和营养的信息。 地址为&#xff1a;https://wwwn.cdc.gov/nchs/nhanes/Default.aspx 既往咱们…

世界前沿技术发展报告2023《世界航空技术发展报告》(六)航空动力技术

&#xff08;六&#xff09;航空动力技术 1.军用航空动力技术1.1 美国空军授出下一代自适应推进项目合同1.2 法国完成下一代战斗机发动机原型机地面测试1.3 美国通用电气公司为美国陆军测试首台T901涡轴发动机1.4 美国液体活塞公司研制高功重比重油发动机 2.民用航空动力技术2.…

这样刻《少年强则国强》也行……

孙溟㠭篆刻《少年强则国强 》 这是篆书&#xff0c;隶书&#xff0c;简化字刻法有点意思。 孙溟㠭篆刻《少年强则国强》

信息系统项目管理师教程 第四版【第7章-项目立项管理-思维导图】

信息系统项目管理师教程 第四版【第7章-项目立项管理-思维导图】 课本里章节里所有蓝色字体的思维导图

一文告诉你样机是什么,分享几个常用的样机模板

一个项目的诞生通常需要经历头脑构思、绘制设计和最终着陆。在这个过程中&#xff0c;样机制作往往是在着陆实践之前进行的。俗话说&#xff1a;“样机使用得好&#xff0c;草稿过早”。样机设计是产品或网站最终设计的生动、静态和视觉表现。它为用户提供了一种模拟现实的方式…

大语言模型有什么魅力?和生成式AI是一回事吗?亚马逊云科技可以告诉你

大语言模型和生成式AI有什么关系呢&#xff1f;大语言模型为什么这么火&#xff1f;一提到大语言模型&#xff0c;想必大家第一个想到的就是ChatGPT这样的自然语言处理工具&#xff0c;那么大语言模型是什么&#xff1f;大语言模型和生成式AI是什么关系&#xff1f;就让我以亚马…

HackerOne 已向白帽支付了超 3 亿美元漏洞赏金

知名网络安全公司HackerOne近日宣布&#xff0c;自2012年成立以来&#xff0c;其漏洞赏金计划已向白帽和漏洞研究人员发放了超 3 亿美元的奖励。 HackerOne提供了一个漏洞赏金平台&#xff0c;将企业与白帽的安全专业知识、资产发现、持续评估和流程增强相结合&#xff0c;以发…

OSEK-任务调度机制

如下图所示&#xff0c;在调度表中有很多 Expiry Points&#xff0c;下面是一个20ms的调度表。有每2.5ms触发一次2.5ms的TASK&#xff0c;以及等等其他按照时间的TASK触发&#xff1b;并且根据配置也可以看出&#xff0c;所有的任务都是基于全抢占模式触发的&#xff0c;也就是…

如何完全卸载HbuilderX(全网最详细)

前序 今天本来想发行打包安卓端,结果发现突然就不行了(前天还行)报错 排查 然后我找了各种原因,排查了很久才发现是HbuilderX编辑器的问题,机智如我所以我们需要重新去下载一个HbuilderX,但是问题来了,很多人不知道怎么卸载,我自己网上也百度了很久没有正确简单的方法,直…

c: two-dimensional array

/*** ****************************************************************************** file twoDimensional.h* brief 二维数组 Pointers and 2-D arrays* author geovindu,Geovin Du,涂聚文 (geovindu163.com)* ide: vscode c11,c17 windows 10* date…

2023年N1叉车司机证模拟考试题库及N1叉车司机理论考试试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2023年N1叉车司机证模拟考试题库及N1叉车司机理论考试试题是由安全生产模拟考试一点通提供&#xff0c;N1叉车司机证模拟考试题库是根据N1叉车司机最新版教材&#xff0c;N1叉车司机大纲整理而成&#xff08;含2023年…

生产级 React 框架介绍

文章目录 生产级 React 框架生产级 React 框架Next.jsRemixGatsbyExpo 如何选择生产级 React 框架 生产级 React 框架 React 是一个流行的 JavaScript 框架&#xff0c;用于构建用户界面。React 框架可以帮助你快速构建高质量的 React 应用&#xff0c;但并不是所有的 React 框…