当前位置: 首页 > news >正文

React Zustand 学习笔记(对照Vue3)

React & Zustand 学习笔记

Codex和Claude Coder这些viber coding似乎更加偏爱react的技术栈,既然这些AI根喜欢,那我们就迁就他,能少写点bug就好。所以对比vue3问了codex一些问题帮助在有vue基础的情况下快速理解react,这里把笔记贴出来方便复习。

React 核心理念

  • UI = f(state):组件是纯函数,传入相同的 props/state 总能得到相同的 UI。
  • Hooks(useStateuseEffectuseMemo 等)提供状态、生命周期、副作用管理,函数组件无需类即可掌握全部能力。
  • Fiber 架构把渲染拆成可中断/恢复的任务,每个 Fiber 节点携带 props、state、effectTag 等信息,协调器根据优先级安排重渲与副作用提交。
  • Diff 机制会比较新旧虚拟 DOM,只把真实 DOM 中的差异打补丁,保持渲染高效。

JSX 速览

const button = <button className="primary">Click</button>;
  • .tsx/.jsx 文件 + tsconfig.json 配置 jsx: "react-jsx" 后,编译器会把 JSX 转成 React.createElement 调用。
  • 小写标签映射到原生元素,大写代表自定义组件。
  • TypeScript 会根据组件 props/children 做类型检查。

React 状态管理

局部状态:useState

  • 组件里调用 useState 会在当前 Fiber 上注册一个 Hook 节点,记录 memoizedStatequeue
  • setState 会把 update 放进 queue,并标记 Fiber 需要更新;下一次渲染重新执行组件函数,生成新的 UI。

全局状态:Zustand

  • createWithEqualityFn 返回的 useStore Hook 把外部 store 接入 React,底层使用 useSyncExternalStoreWithSelector
  • Store 初始化函数 (set, get) => ({ ... }) 中的 set/get 由 Zustand 注入,分别负责写入和读取最新状态。
  • useCounterStore((state) => state.count) 中的箭头函数是 selector,只订阅所需切片;Zustand 比较 selector 新旧结果,不变就跳过组件重渲。
  • 想要广播更新,必须调用 store 暴露的 action(例如 increment)或 setState,单纯修改本地变量不会同步。
示例:Zustand 计数器
// counterStore.ts
import { createWithEqualityFn } from "zustand/traditional";interface CounterState {count: number;step: number;increment: () => void;reset: () => void;
}export const useCounterStore = createWithEqualityFn<CounterState>()((set, get) => ({count: 0,step: 1,increment: () => set(({ count, step }) => ({ count: count + step })),reset: () => set({ count: 0 }),
}));
// FastCounter.tsx
import { memo } from "react";
import { useCounterStore } from "../store/counterStore";export const FastCounter = memo(() => {const count = useCounterStore((state) => state.count);const increment = useCounterStore((state) => state.increment);return (<div><h1>Count: {count}</h1><button onClick={increment}>+1</button></div>);
});

React 渲染与订阅

  • useSyncExternalStore 是 React 18 提供的官方订阅 API。
    • subscribe(onStoreChange) 注册监听;React 在 commit 阶段调用订阅函数。
    • getSnapshot() 同步读取当前快照;React 在每次重渲前后用 Object.is 对比新旧值。
    • SSR 下可选 getServerSnapshot(),保持水合一致。
  • useSyncExternalStoreWithSelector 额外支持 selector/equalityFn,Zustand、Redux Hooks 都基于它实现。
  • 组件里的 useState/useReducer 更新也是同样流程:setState → 在 Fiber 上挂 update → 调度器重新执行组件函数 → diff → commit。

React vs Vue 对比

  • 语法:Vue SFC 模板 + 指令;React 使用 JSX,逻辑与视图合体。
  • 状态模型:Vue 基于响应式 Proxy 自动追踪依赖;React 采用显式 setState,依靠虚拟 DOM diff 获取变化。
  • 组件通信:Vue 提供 props/emit,也可传函数;React 统一用 props/回调 + 状态提升。
  • 生态:Vue 有 Pinia、Router 官方支持;React 生态更去中心化,需要自行选择 Zustand/Redux、React Router 等。
  • 双向绑定:Vue 有 v-model;React 通过受控组件(value + onChange)模拟,仍是单向数据流。

React 与 Vue 迁移提示

  • 可以把 hooks 看成 Vue 的组合式 API:useStaterefuseEffectwatchEffect/生命周期,useMemocomputed
  • 父组件感知子组件变化通常传入回调函数,不存在内置 emit,但本质和 Vue 传函数 props 类似。

SSR(Server-Side Rendering)

  • 在服务器预先渲染 HTML,客户端接收后再 hydrate,提升首屏速度与 SEO。
  • useSyncExternalStoregetServerSnapshot 参数帮助在 SSR 中提供一致快照,避免水合警告。

常见问答备忘

  • React 会自动追踪普通变量吗? 不会,必须通过 setState 或 store action 明确触发更新。
  • Zustand selector 返回的值可直接修改吗? 不可,它只是一个快照;需要调用 action 更新。
  • set 会导致循环更新吗? 不会,set 内部只执行一次:读取旧值 → 计算新值 → 写入 → 通知订阅者,除非你在 effect 中再次触发 set。
  • Fiber 和 Vue VNode 一样吗? Fiber 不仅描述节点,还存储调度信息(优先级、更新队列、effectTag),用于实现可中断渲染。

React/Vue 对照小示例

React Counter(受控 + 历史)

import { useState, useEffect } from "react";export function Counter({ initial = 0, step = 1 }: { initial?: number; step?: number }) {const [count, setCount] = useState(initial);const [history, setHistory] = useState<number[]>([]);useEffect(() => {setHistory((prev) => [...prev, count]);}, [count]);return (<section><h1>Count: {count}</h1><button onClick={() => setCount((prev) => prev + step)}>+{step}</button><button onClick={() => { setCount(initial); setHistory([]); }}>Reset</button><p>History: {history.join(" → ") || "Empty"}</p></section>);
}

Vue 3 Composition API 等价实现

<script setup lang="ts">
import { ref, watch, withDefaults, defineProps } from "vue";interface Props { initial?: number; step?: number; }
const props = withDefaults(defineProps<Props>(), { initial: 0, step: 1 });const count = ref(props.initial);
const history = ref<number[]>([]);watch(count, (value) => {history.value = [...history.value, value];
});const handleIncrement = () => { count.value += props.step; };
const handleReset = () => { count.value = props.initial; history.value = []; };
</script><template><section><h1>Count: {{ count }}</h1><button @click="handleIncrement">+{{ props.step }}</button><button @click="handleReset">Reset</button><p>History: {{ history.length ? history.join(' → ') : 'Empty' }}</p></section>
</template>

术语速记

  • Hook:函数组件里调用的 React API,例如 useStateuseEffect
  • Fiber:React 的内部数据结构,表示组件节点并携带调度信息。
  • Selector:在 Zustand/Redux 中用于挑选 store 切片的函数。
  • Hydration:SSR 输出的 HTML 在客户端由 React/Vue 接管的过程。
  • useSyncExternalStore:把外部数据源接入 React 渲染流程的官方 Hook。
http://www.dtcms.com/a/410380.html

相关文章:

  • PyTorch实现CIFAR-10图像分类:从数据加载到模型训练全流程
  • 鸿蒙应用内存优化全攻略:从泄漏排查到对象池实战
  • ReactUse 与ahook对比
  • 网站建设与维护属于什么岗位wordpress免费企业站主题
  • 长安网站设计仿照别的网站做
  • 如何快速定位bug,编写测试用例?
  • 【LeetCode 142】环形链表 II:寻找环的入口
  • 卷轴 缓冲绘制 超级玛丽demo5
  • 1.9 IP地址和Mac地址
  • C# WinForms的入门级画板实现
  • 云南网站建设方案简述营销型网站开发流程
  • 随时随地学算法:Hello-Algo与cpolar的远程学习方案
  • App 上架全流程指南,iOS 应用发布步骤、ipa 文件上传工具、TestFlight 分发与 App Store 审核经验分享
  • 网站建设公司推荐常德网站开发服务
  • 全球知名的Java Web开发平台Vaadin上线慧都网
  • 【QT】高级主题
  • 详细对比web请求post和put的区别
  • dedecms 营销网站模板免费下载专业设计网址青岛网站开发
  • 正在招 | 2025.9 福建 IT 相关岗位招聘信息
  • 树莓派4B+ubuntu20.04:不插显示器能不能正常开机?
  • 开发大型网站的最主流语言上海seo网站优化_搜索引擎排名_优化型企业网站建设_锦鱼网络
  • 从远程控制到AI赋能:ToDesk如何重塑未来办公新生态?
  • Python爬虫进阶:突破反爬机制(UA伪装+代理池+验证码识别)
  • 华为发布开源超节点架构,以开放战略叩响AI算力生态变局
  • 从格伦的角度理解信息哲学
  • 网站建设分金手指专业三十WordPress 多用户数据
  • obsidian git操作及踩坑记录:ssh秘钥设置以及推送到多个远程仓库
  • 【Linux】网络部分——网络基础(Socket 编程预备)
  • 【音频】SIP服务器Yate搭建
  • 贵阳网站建设宏思锐达网站挂服务器后图片不显示