2025年,你必须要知道的react状态管理!

重新认识React状态本质

React 的状态(State)是组件内部管理动态数据的核心机制,它不仅是数据容器,更是视图更新的触发器。是react项目中最重要没有之一的一种数据,说白了,这个所谓的状态变了,页面就变,非状态的数据变了页面不会有任何变化,只要处理好:引起状态变化=>状态变化处理=>状态变化反映到页面中这个核心流程,就能写出高性能的页面。

状态的核心特征

  • 响应性:状态与视图自动保持同步
  • 局部性:默认隔离在组件作用域内
  • 可预测性:通过setState等API进行受控变更

状态提升的六大途径

React提供了多维度的状态管理方案:

  1. 组件内状态useState/useReducer
  2. 组件间传递Props Drilling
  3. 全局共享Context API
  4. 外部存储useSyncExternalStore
  5. 状态库集成Redux/Zustand
  6. 服务端同步TanStack Query

现代状态管理分层架构

React中的状态可以分为全局状态和局部状态,局部状态就是组件中私有的状态比如一个计数器组件中的"数",全局状态说白了就是一些需要深层级传递的状态。那么什么是状态管理呢?其实就是用类似Context Api和Redux、zustand这种库来把一些需要深层级传递的状态收集起来,方便后续项目中使用。

而全局状态又可以分成两种类型:客户端状态和服务端状态,前者只存在于应用程序内部,而后者在应用程序外部持久存在,所以显而易见,状态管理也应该区分开两种情况。其中客户端状态使用zustand等库就可以完美进行管理,要优雅的处理服务端的状态就要用到Tanstack Query这个库了。

客户端状态管理(zustand最佳实践)

什么叫只存在应用程序内部呢?举个例子,UI交互状态(弹窗开关、表单填写)、主题配色方案、本地用户偏好设置等等。zustand的store也只应该存储这些。来看一下合理的实践。

简单的几行代码,就托管了theme这个客户端状态

我自己以前在平时项目开发中经常将请求中拿过来的一堆数据存在上面那些工具中,给项目的store创造了一个个schema,然后用着很爽,类型还安全。殊不知这样处理项目中的状态结构十分混乱,非常不利于后续的维护。其实是弄混了客户端状态与服务端状态的定位。

服务端状态管理(TanStack Query深度整合)

在应用程序外部持久存在,换句话说,就是你从服务端靠请求拿到的需要显示在页面上的数据。

我们先来看下如何使用tanstack query

js 复制代码
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'

// 创建一个`QueryClient`实例,该实例可以理解为zustand的那种全局的store
const queryClient = new QueryClient()

function App() {
  return (
    // 将该实例传入到QueryClientProvider中 ,像context那样在根组件上包一层
    <QueryClientProvider client={queryClient}>
      <Test />
    </QueryClientProvider>
  )
}

在这里创建的这个QueryClient实例后面我们就可以用useQueryClient来拿到从而对存入里面的服务端状态进行一些神奇的处理,比如乐观更新等等。

我们来看一下基本的使用:

在上图中展示了useQueryuseMutation这两个最重要的hook。

useQuery需要我们提供querykey(一个数组)以及一个返回promise的queryFn,querykey可以理解为在刚刚创建好的QueryClient中对这个query的唯一标识,后面通过这个querykey我们可以从QueryClient取出这个key对应的数据或者对这个query存储的数据进行更改或者重新验证。该hook返回query,该对象中保存着对于这次查询你所应该知道的所有数据包括

  • data:本次查询返回的数据。
  • error:请求失败时对应的错误对象。
  • isPending / status === 'pending':还没有数据。
  • isError / status === 'error':请求出错。
  • isSuccess / status === 'success':请求成功并且数据可用状态。
  • isFetching / fetchStatus === 'fetching':正在请求数据中。
  • isPaused / fetchStatus === 'paused':请求暂停中。
  • fetchStatus === 'idle':当前没有任何请求,处于空闲中。

useMutation接受一个mutationFn和突变后的回调,和useQuery类似,他返回一个mutation对象,通过该对象你可以得到这次突变所有状态信息,并且可以调用上面的mutate方法发起一次突变。

tanstack query通过一个请求库的存在形式,帮您在项目中发出一切请求,然后自动的缓存他们,通过开发者的配置可以更改缓存的时间,重试的次数等等,让项目中的服务端状态系统的管理起来,让全局状态更加的清晰。

In this situation it's important to note that TanStack Query is not a replacement for local/client state management. However, you can use TanStack Query alongside most client state managers with zero issues.

需要注意的是,TanStack Query 不能替代本地/客户端状态管理(比如 Zustand、Mobx、Valtio 等)。但是,您可以将 TanStack 查询与大多数客户端状态管理库一起使用,而不会出现任何问题。

在当前React生态中,状态管理已从单一方案发展为分层架构。建议将75%的服务端状态交由TanStack Query管理,20%的UI状态使用zustand处理,剩余5%的派生状态通过useMemo优化。这种黄金分割比例既能保证代码可维护性,又能获得最佳运行时性能。

相关推荐
花楸树8 分钟前
前端搭建 MCP Client(Web版)+ Server + Agent 实践
前端·人工智能
wuaro8 分钟前
RBAC权限控制具体实现
前端·javascript·vue
专业抄代码选手13 分钟前
【JS】instanceof 和 typeof 的使用
前端·javascript·面试
用户00798136209713 分钟前
6000 字+6 个案例:写给普通人的 MCP 入门指南
前端
用户876128290737418 分钟前
前端ai对话框架semi-design-vue
前端·人工智能
干就完了120 分钟前
项目中遇到浏览器跨域前端和后端解决方案以及大概过程
前端
我是福福大王23 分钟前
前后端SM2加密交互问题解析与解决方案
前端·后端
实习生小黄26 分钟前
echarts 实现环形渐变
前端·echarts
_未知_开摆33 分钟前
uniapp APP端在线升级(简版)
开发语言·前端·javascript·vue.js·uni-app
sen_shan1 小时前
Vue3+Vite+TypeScript+Element Plus开发-02.Element Plus安装与配置
前端·javascript·typescript·vue3·element·element plus