快速上手:10分钟完成Granite TimeSeries FlowState R1的Docker部署与测试

核心内容摘要

基于强化学习和大模型的船舶避碰系统(源码+lw+部署文档+讲解等)
小学生玩转Arduino------DIY炫彩流水灯

HTTP协议之状态码详解

有网友问到React那么多状态库能不能直接焊死一个那就简单聊下我的看法仅供参考。

篇幅比较长中间的代码示例大家可以跳着阅读。

主流状态管理库分类

客户端状态管理Redux Toolkit (RTK) - 最成熟企业级首选Zustand - 轻量简洁API 友好Jotai - 原子化状态React 风格Recoil - Facebook 出品实验性Valtio - 代理基础可变语法

服务端状态管理TanStack Query(React Query)- 异步数据王者SWR - Vercel 出品轻量RTK Query- Redux 生态内

全栈/框架集成Next.js- 内置多种方案Remix - 基于 loader/actionNuxt(Vue)- 类比参考 我的建议焊死这个组合对于大多数项目如果非要焊死一个的话我推荐Zustand TanStack Query。

React 太多状态管理库了如果非要焊死一个我目前推荐这个王炸组合。

为什么选择这个组合

先搞懂为什么要分开处理两种状态在开始安利组合之前我们得先明确一个核心认知React 项目中的状态从来都不是一锅炖的而是分为两种截然不同的类型需要区别对待。

客户端本地状态UI 状态比如按钮的禁用状态、侧边栏的展开 / 折叠、导航栏的当前选中项、用户的本地偏好设置等。

这类状态的特点是同步更新、无需缓存、仅在客户端生效、数据量较小。

服务端异步状态接口数据比如从后端获取的用户列表、文章数据、商品信息等。

这类状态的特点是异步获取、需要处理 loading/error 状态、需要缓存、可能需要后台刷新、支持分页 / 无限加载。

过去我们总想着用一套方案搞定所有状态结果就是既要又要还要最后搞得不伦不类。

而Zustand TanStack Query的组合正是精准切中了这两种状态的需求各司其职、强强联合。

Zustand客户端状态管理的「极简天花板」Zustand 是一款轻量、简洁、API 友好的客户端状态管理库它的核心理念就是少即是多—— 没有繁琐的概念没有多余的模板代码甚至不需要Provider包裹整个应用上手即用。

核心优势为什么放弃 Redux 选择 Zustand代码量减少 70%无需写 Action、Reducer无需配置 Provider直接创建 Store 即可使用。

无需 Provider 包裹告别顶层嵌套的 Provider 地狱尤其是在大型项目中能极大简化组件树结构。

TypeScript 支持完美内置 TypeScript 类型推导无需额外写大量类型声明写起来丝滑流畅。

⭐JavaScript 无缝兼容无需额外配置类型原生 JS 写起来丝滑流畅新手也能快速上手。

足够应对 95% 的客户端状态需求支持中间件、持久化、状态切片扩展性拉满小型项目和中型项目都能 hold 住。

超小体积核心体积不到 1KB对项目打包体积几乎没有影响堪称「轻量王者」。

代码示例5 分钟上手 Zustand第一步安装依赖npm install zustand # 或 yarn add zustand # 或 pnpm add zustand第二步创建第一个 Store我们来写一个最简单的计数器感受一下Zustand的简洁// src/store/count.store.js import { create } from zustand; // 创建计数器 Store const useCountStore create((set) ({ // 定义状态数据 count: 0, // 定义修改状态的方法无需 Action直接修改 increase: () set((state) ({ count: state.count 1 })), decrease: () set((state) ({ count: state.count - 1 })), reset: () set({ count: 0 }), // 支持传入参数修改状态 setCount: (num) set({ count: num }), })); export default useCountStore;// scr/App.jsx import useCountStore from ./store/count.store.js export default function App() { return ( div h1Count: {useCountStore((state) state.count)}/h1 /div ) }第三步在组件中使用 Store无需任何额外配置直接导入使用就是这么简单// src/components/CountComponent.jsx import useCountStore from ../store/count.store; const CountComponent () { // 按需获取状态和方法支持解构不会触发不必要的重渲染 const count useCountStore((state) state.count); const { increase, decrease, reset } useCountStore(); return ( div style h3 styleZustand 计数器示例/h3 p style当前计数{count}/p div button onClick{increase} style 1 /button button onClick{decrease} style -1 /button button onClick{reset} style 重置 /button /div /div ); }; export default CountComponent;进阶示例 Zustand 持久化本地存储用户偏好如果需要将状态持久化到localStorage比如用户的侧边栏偏好Zustand 也能轻松实现只需借助内置的中间件// src/store/ui.store.js import { create } from zustand; import { persist } from zustand/middleware; // 创建 UI 状态 Store并开启持久化 const useUiStore create( persist( (set) ({ // 侧边栏展开状态 sidebarCollapsed: false, // 切换侧边栏状态 toggleSidebar: () set((state) ({ sidebarCollapsed: !state.sidebarCollapsed })), }), { // 持久化的 key用于 localStorage 中存储的键名 name: ui-preferences, } ) ); export default useUiStore;使用起来和普通 Store 毫无区别但是状态会自动同步到 localStorage页面刷新后也不会丢失个人觉得还是挺方便的。

TanStack Query服务端状态管理的「异步王者」如果说Zustand是客户端状态的极简天花板那么TanStack Query原 React Query就是服务端状态的异步王者。

它的核心作用是帮你封装了所有服务端数据处理的繁琐逻辑让你像使用本地状态一样使用异步接口数据。

你再也不用手动处理 loading、error、缓存、重试这些问题只需专注于编写接口请求函数即可。

核心优势为什么选择 TanStack Query自动缓存请求的数据会自动缓存相同的请求不会重复发送极大减少接口请求次数。

自动处理 loading/error 状态内置 loading、error、data 状态无需手动声明和更新。

后台数据同步支持后台刷新数据页面在前台时自动更新最新数据无需用户手动刷新。

内置分页 / 无限加载 / 乐观更新提供丰富的 Hooks 支持复杂的异步数据场景无需自己造轮子。

自动重试请求失败时可以配置自动重试提高接口的容错性。

强大的 DevTools配套的开发者工具能清晰看到请求的缓存、状态、历史记录调试更方便。

代码示例5 分钟上手 TanStack Query第一步安装依赖npm install tanstack/react-query tanstack/react-query-devtools # 或 yarn add tanstack/react-query tanstack/react-query-devtools # 或 pnpm add tanstack/react-query tanstack/react-query-devtools第二步全局配置 TanStack Query首先需要在项目入口文件中配置QueryClient和QueryClientProvider这是唯一需要全局配置的步骤// src/main.jsx import React from react; import ReactDOM from react-dom/client; import App from ./App; import { QueryClient, QueryClientProvider } from tanstack/react-query; import { ReactQueryDevtools } from tanstack/react-query-devtools; // 创建 QueryClient 实例 const queryClient new QueryClient({ defaultOptions: { queries: { // 默认开启缓存5 分钟内不重复请求 staleTime: 5 * 60 * 1000, // 请求失败时自动重试 3 次 retry: 3, // 关闭无限加载可选 refetchOnWindowFocus: false, }, }, }); const root ReactDOM.createRoot(document.getElementById(root)); root.render( QueryClientProvider client{queryClient} App / {/* 挂载 DevTools开发环境开启生产环境可移除 */} ReactQueryDevtools initialIsOpen{false} / /QueryClientProvider );第三步封装接口请求 Hook我们来封装一个获取待办事项的 Hook感受一下 TanStack Query 的强大// src/api/todos.api.js import { useQuery, useMutation, useQueryClient } from tanstack/react-query; //

定义接口请求函数 const fetchTodos async () { const response await fetch(https://jsonplaceholder.typicode.com/todos); if (!response.ok) { throw new Error(获取待办事项失败); } return response.json(); }; //

定义新增待办事项的函数纯 JavaScript const addTodo async (newTodo) { const response await fetch(https://jsonplaceholder.typicode.com/todos, { method: POST, headers: { Content-Type: application/json, }, body: JSON.stringify(newTodo), }); if (!response.ok) { throw new Error(新增待办事项失败); } return response.json(); }; //

封装获取待办事项的 Hook使用 useQuery纯 JavaScript export const useTodosQuery () { return useQuery({ // queryKey缓存的唯一标识必须是数组类型支持依赖项传递 queryKey: [todos], // queryFn接口请求函数 queryFn: fetchTodos, }); }; //

封装新增待办事项的 Hook使用 useMutation处理 POST/PUT/DELETE 请求 export const useAddTodoMutation () { const queryClient useQueryClient(); return useMutation({ mutationFn: addTodo, // 新增成功后自动刷新待办事项列表乐观更新 onSuccess: () { queryClient.invalidateQueries({ queryKey: [todos] }); }, }); };第四步在组件中使用接口 Hook无需手动处理 loading 和 error直接解构使用即可代码简洁到飞起// src/components/TodoComponent.jsx import React, { useState } from react; import { useTodosQuery, useAddTodoMutation } from ../api/todos.api; const TodoComponent () { const [title, setTitle] useState(); // 获取待办事项数据 const { data: todos, isLoading, isError, error } useTodosQuery(); // 新增待办事项 const { mutate: addTodo, isPending: isAdding } useAddTodoMutation(); // 处理新增待办事项提交 const handleSubmit (e) { e.preventDefault(); if (!title.trim()) return; addTodo({ title, completed: false }); setTitle(); }; // 加载中状态 if (isLoading) { return div style正在获取待办事项.../div; } // 错误状态 if (isError) { return div style获取失败{error.message}/div; } return ( div style h3 styleTanStack Query 待办事项示例JSX/h3 {/* 新增待办事项表单 */} form onSubmit{handleSubmit} style input typetext value{title} onChange{(e) setTitle(e.target.value)} placeholder请输入待办事项 style / button typesubmit disabled{isAdding} style {isAdding ? 新增中... : 新增待办} /button /form {/* 待办事项列表 */} div h4待办列表前 10 条/h4 ul style {todos?.slice(0,

.map((todo) ( li key{todo.id} style {todo.title} /li ))} /ul /div /div ); }; export default TodoComponent;运行代码后你会发现请求自动发送、加载状态自动处理、新增数据后列表自动刷新、相同请求不会重复发送 —— 这一切都是 TanStack Query 帮你做好的你只需要专注于业务逻辑即可。

王炸组合落地项目结构最佳实践看完了两个库的单独使用我们再来看看如何在实际项目中整合 Zustand TanStack Query打造一个清晰、可维护的项目结构。

src/ ├── store/ # Zustand 客户端状态存储目录 │ ├── auth.store.js # 认证相关状态登录状态、用户信息 │ ├── ui.store.js # UI 相关状态侧边栏、主题、导航 │ └── index.js # Store 导出汇总方便组件导入 ├── api/ # TanStack Query 接口 Hook 目录 │ ├── todos.js # 待办事项相关接口 │ ├── users.js # 用户相关接口 │ └── index.js # 接口 Hook 导出汇总 ├── components/ # 公共组件目录 ├── pages/ # 页面组件目录 └── App.jsx # 根组件 快速决策指南可能有人会问我的项目很小需要用这套组合吗我的项目是大型企业级项目这套组合够用吗别急我让DeepSeek给大家整理了一份懒人快速决策指南对应不同场景选择最合适的方案超简单状态单个组件内、无需共享直接用useState即可无需引入任何状态库简单直接。

小型项目 / 简单共享状态少量组件共享状态可以用React Context useReducer或者直接用 Zustand上手更快代码更简洁。

中型项目推荐90% 的项目场景直接焊死Zustand TanStack Query开发体验最佳覆盖 99% 的场景后期维护成本低。

大型企业级项目需要强架构、可追溯、团队协作可以选择Redux Toolkit RTK Query支持时间旅行调试、丰富的中间件生态适合对架构有严格要求的大型项目。

超极简需求只需要原子化状态可以选择Jotai或nanostores原子化状态管理按需更新体积更小。

具体落地建议//

安装核心依赖 dependencies: { zustand: ^

4.

0, tanstack/react-query: ^

5.

0, tanstack/react-query-devtools: ^

5.

0 } //

项目结构 src/ ├── store/ # Zustand stores │ ├── auth.store.ts │ ├── ui.store.ts │ └── index.ts ├── api/ # TanStack Query hooks │ ├── todos.ts │ └── users.ts └── components/ 迁移策略如果你现在用Redux逐步迁移新功能用Zustand旧功能保持Redux两者可以共存 黄金法则先判断状态类型服务器数据→TanStack Query客户端 UI 状态→Zustand表单状态→React Hook Form Zustand避免过度设计能用useState就别用状态库组件内状态优先共享状态才提升技术选型标准团队熟悉度维护活跃度TypeScript 支持Bundle 大小️ 最终答案非要焊死的话那我推荐这个组合Zustand TanStack Query这个组合能覆盖✅ 客户端状态Zustand✅ 服务端状态TanStack Query✅ 表单状态React Hook Form✅ URL 状态React Router对于 90% 的 React 项目这套组合是最佳实践。

除非你有特殊需求如需要 Redux 中间件生态或时间旅行调试。

结语到这里相信大家已经对 Zustand TanStack Query 这套王炸组合有了全面的了解。

这套组合的核心魅力就在于简洁、高效、各司其职。

Zustand 搞定客户端本地状态让你告别繁琐的 Provider 和模板代码TanStack Query 搞定服务端异步数据让你告别手动处理 loading/error/ 缓存的烦恼。

祝大家编码愉快少写 bug多摸鱼

尾随打胶射鞋视频-尾随打胶射鞋视频应用

百度百家号客服电话人工服务

123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123