React学习心得分享: React 对比 Vue

19 天前
/ ,
26
摘要
小满的课程,上班时候学的,上班的时候不能看视频,全是看文档学习的,Gemini3.7执笔,我修改少部分细节

React学习心得分享: React 对比 Vue

前言:一直以来,Vue 都是我的主力前端框架。从模板语法、响应式数据到组合式 API,Vue 的“开箱即用”和“保姆级体验”伴随我完成了许多项目。最近,我系统地学习了小满老师的 React Docs 文档,将 React 作为我的第二门前端框架正式纳入口袋。

虽然目前我刚刚学完整个教程、还没有在实际商业项目中完整踩过实战的坑,但这套体系化学习下来,我最大的感受就是:React 和 Vue 的底层世界观完全不同。

下面对照这份 React 文档的知识脉络(基础语法、编译工具、底层原理、组件体系、CSS 方案、Hooks 全家桶、路由与状态管理),结合我熟悉的 Vue,写下这份初学者视角的框架对比与心得笔记。


1. 入门与语法:模板指令 vs “一切皆是 JS”

打开文档的第一章,就是 TSX(JSX)语法。对于习惯了 Vue 模板语法的开发者来说,这是第一道冲击。

业务场景Vue (Template 语法糖)React (TSX / JS 表达式)体验感受
数据插值{{ message }}{message}React 用单大括号,里面可以写任意合法的 JS 表达式。
条件渲染v-if="flag" / v-elseflag ? <A /> : <B />flag && <A />Vue 是指令化思维;React 完全靠原生 JS 的三元运算符和短路求值。
列表渲染v-for="item in list" :key="item.id"list.map(item => <li key={item.id}>{item.name}</li>)React 没有特定指令,就是原生数组的 .map()
事件绑定@click="handleClick"onClick={handleClick}驼峰命名,传函数引用。
类名绑定:class="{ active: isActive }"className={isActive ? 'active' : ''}React 中 class 是 JS 关键字,必须写 classNamefor 需写成 htmlFor

学习感受:

  • Vue 的感受是“规整”:Vue 给开发者设计好了各种指令(v-if, v-for, v-model),模板结构清晰,HTML 该长什么样就是什么样。
  • React 的感受是“自由”:TSX 根本不是模板,它本质上就是 JavaScript 语法扩展。不用记框架自创的指令语法,只要 JS 基础好,就可以随意用 if/elsemapfilter 来组装 UI。

2. 构建与编译工具:Babel / SWC vs Vue SFC Compiler

文档在“工具篇”特意讲解了 BabelSWC

  • React 的转译本质:我们写的 <div className="box">Hello</div>,经由 Babel 或 SWC 转译后,本质上是变成 React.createElement('div', { className: 'box' }, 'Hello')(或者新的 _jsx('div', ...))。
  • 对比 Vue:Vue 的核心是 SFC(单文件组件 .vue),由 @vitejs/plugin-vue 解析,将 <template> 编译为高效的 render 函数,并将 <script><style> 分离处理。

学习感受:

通过文档手写 Babel/SWC 转译示例后我才明白:React 的组件真的就是一个返回虚拟 DOM 对象的纯 JS 函数,它没有 Vue SFC 那么强的结构专属感。


3. 核心原理篇:不可逆的时间切片与细粒度响应式

文档中关于 VDOM、Fiber、Diff 以及&#32;requestIdleCallback 的章节是我读得最过瘾、也最烧脑的部分。

① Fiber 架构与双缓存机制

  • React 的痛点与解法:早期的 React 递归遍历 VDOM 树,如果组件树太深就会长期霸占主线程导致页面掉帧卡顿。于是 React 16 彻底重构为 Fiber 架构,把树状结构变成了链表结构,借助浏览器空闲调度(类似 requestIdleCallback)实现可中断、可恢复的异步更新(时间切片)。并通过“当前树 (current)”与“工作树 (workInProgress)”双缓存交替来提高渲染稳定性。
  • Vue 的解法(靶向更新):Vue 根本不需要 Fiber 这种复杂的时间切片!因为 Vue 拥有基于 Proxy 的精准依赖收集。Vue 在编译时做了大量静态标记(PatchFlag、静态提升),数据变化时,直接精准定位到对应的组件或具体 DOM 节点进行打补丁,更新开销极小。

② Diff 算法差异

  • React Diff:同层比较,仅支持向右移动单向比较,若 key 匹配但位置靠前,可能会引发多余的移动操作。
  • Vue Diff:Vue 2 采用双端 Diff(头头、尾尾、头尾交叉对比),Vue 3 采用基于最长递增子序列的快速 Diff,在 DOM 移动次数的优化上更加极致。

4. 组件体系:单向流动的严谨与灵活

文档中的组件篇涵盖了组件通信、受控组件、Portal、Suspense 和 HOC(高阶组件)。

① 受控组件 vs v-model

这是初学 React 时最容易手忙脚乱的地方:

  • Vue:一个 v-model="text" 搞定双向绑定。
  • React:必须显式声明为受控组件
<input value={text} onChange={(e) => setText(e.target.value)} />
数据流完全单向,状态必须从上往下传,改动必须通过事件触发通知更新。

② 插槽 vs children & Render Props

  • Vue:拥有极其完善的插槽系统(默认插槽、具名插槽 <template #header>、作用域插槽)。
  • React:默认内容直接通过 props.children 获取;如果需要作用域插槽的效果,直接传一个函数即可(Render Props 模式:props.render(data)),纯 JS 函数传参,简单直接。

③ 传送组件与异步组件

  • 传送组件:React 的 createPortal(JSX, domNode) 对标 Vue 的 <Teleport to="body">
  • 异步加载:React 的 lazy(() => import(...)) + <Suspense fallback={<Loading />} /> 对标 Vue 的 defineAsyncComponent + <Suspense> (但是这部分我在Vue里面没怎么用过...)

④ 高阶组件 (HOC)

React 拥有丰富的高阶组件文化(接收组件并返回增强后的新组件),而 Vue 社区在进入 Vue 3 后基本统一推崇 Composition API,极少使用 HOC, React在更多的Hooks支持下, HOC的使用场景也被大大压缩, 平时开发听小满说根本用不到。


5. CSS 方案:自由探索 vs 开箱即用

在 Vue 里,我们最习惯的写法是:

<style scoped>
.title { color: red; }
</style>

scoped 属性通过 PostCSS 自动给 DOM 添加 data-v-xxx 属性选择器,干净又好用。

而在 React 文档中,CSS 方案是一场“百家争鸣”:

  1. CSS Modules:文件命名为 index.module.css,像对象一样 import styles from './index.module.css',通过 className={styles.title} 调用,生成哈希类名隔离, 说到底是没有Vue那种scoped隔离的痛。

  2. CSS-in-JS(如 styled-components / emotion):把样式直接作为组件来写, Ant Design就是用的这种方式写的样式。
  3. Tailwind CSS:原子化 CSS,文档里重点推荐,由于写在 className 里很自然,在 React 社区极为流行, 当然在Vue的圈子里面也极为的流行, 说到底就是极为的流行。

6. 核心重头戏:React Hooks 全家桶 vs Vue 组合式 API

读完整份文档,Hooks 是篇幅最大、也是和 Vue 3 Composition API 思想碰撞最激烈的部分。

useState vs ref / reactive

  • Vue:数据是“可变响应式代理”。
const count = ref(0)
count.value++ // 直接修改,Proxy 自动捕获并派发更新
  • React:强调不可变数据(Immutable)(很傻感觉,DX很不好,得用第三方useImmer去加强DX)
const [count, setCount] = useState(0)
setCount(count + 1) // 必须显式调用 setter,不能直接 count = 1

useEffect vs watch / watchEffect / 生命周期

在 Vue 中,挂载、卸载、监听是各司其职的(onMountedonUnmountedwatch)。
而在 React 中,文档把所有的“副作用”都归拢到了 useEffect 中:

  • 依赖项传 []:相当于 onMounted,返回的清理函数相当于 onUnmounted
  • 依赖项传 [count]:相当于 watch(count, ...)
  • 文档还介绍了更细分的 useLayoutEffect(DOM 变更后、浏览器绘制前同步执行,防闪烁)以及 useInsertionEffect(专为 CSS-in-JS 插入样式设计)。

useMemo & useCallback vs computed(最大的心智负担差异!)

这是我认为 Vue 转 React 最需要适应的核心区别

  • 在 Vue 3 中:组件的 <script setup> 只在初始化时执行一次computed 自动收集依赖,数据变了才重新计算,完全不需要手动管理函数的引用。
  • 在 React 中每次状态变化,整个函数组件就会从头到尾重新执行一遍!
  • 组件内的普通函数每次渲染都会重新声明新的引用,导致传递给子组件时引发子组件无意义的重渲染;
  • 因此必须显式使用 useCallback 缓存函数引用,使用 useMemo 缓存计算密集型结果!

好在后面的Next中已经可以开启Rect Compiler减少这种心智负担, 不然真的会死人的😢

useRef 的双重身份

在 Vue 中 ref 既用来做响应式数据,又用来绑定 DOM。
在 React 中:

  1. 获取 DOM 节点:<div ref={domRef} />
  2. 保存跨渲染周期的可变数据useRef(initialValue) 改变 .current 不会触发组件重新渲染.current可以得到绑定的DOM的值

⑤ 并发特性 Hooks(useTransition & useDeferredValue

文档中还深入到了 React 18 的并发特性:

  • useTransition:把某些不紧急的状态更新(如复杂的列表过滤)标记为低优先级过渡任务,防止输入框打字卡顿。
  • useDeferredValue:延迟派生某个值的更新。
    这展示了 React 面对重型计算和交互优先级调度时的强悍能力。

7. 路由与全局状态管理:React Router 与 Zustand

① 路由篇:React Router v7 vs Vue Router

  • Vue Router:中心化路由配置,配合内置的 <router-view>,导航守卫(beforeEach)非常直观。
  • React Router (v7):有loader和action两个路由的行为, 这个是跟Vue有很大区别的地方, 可以在页面上要Get请求获取数据的地方提前在路由的loader中执行, 页面中需要执行Post提交表单的地方执行路由action里面的逻辑, 提交表单数据, 然后回到页面还能自动执行一次loader获取一次新的数据, 这一点让开发的体感很好, 还有各种Hooks useNavigate(), useParams(), useLoaderData(), useActionData()。
  • React Router还有很多模式, 但是实际上感觉还是使用跟Vue一样 的数据路由模式更好理解。

② 状态管理篇:Zustand vs Pinia

文档在全局状态管理中选择了极其轻巧优雅的 Zustand,而不是笨重的传统 Redux:

import { create } from 'zustand'

const useStore = create((set) => ({
  bears: 0,
  increase: () => set((state) => ({ bears: state.bears + 1 })),
}))
  • 对比 Vue 的 Pinia,两者的开发体验惊人地相似:都摒弃了 Mutation 的概念,体积轻巧,支持直接解构 Hook 使用。
  • 但 Zustand 在内部依然严格遵循 React 的不可变合并思想,写起来非常纯粹。
  • Zustand 还有自定义各种middleware和官方推荐的第三方的middleware就比如Immer, 这个就很好使用, 能不用管React什么傻x的不可变数据原则, 虽然底层还是保留了这个原则。

总结:我的学习感想

学完这整套 React 文档,如果用一句话总结两者的区别:

Vue 像一辆配置自动档位的车:响应式自动追踪、模板指令丰富、Scoped CSS 开箱即用,框架替你处理好了绝大多数优化细节,上手平滑、开发体验极度舒适。 就很自动, 而且三剑客不分离,代码美观易懂 ,新手上手很快,跟着官方走准没错,生态方面差一点。

React 则像一辆纯手动挡的车:没有魔法,纯粹靠原汁原味的 JavaScript 驱动。它的单向数据流、不可变思想和 Fiber 架构非常严谨,但也正因如此,很多优化得自己去调用Hooks。三剑客合家,代码不美观。但是React的生态丰富, 社区热情度更高,有很多UI库和Hooks库,人人都可以处理React麻烦的点,欣欣向荣。

作为刚刚学完理论知识、尚未经历大型项目实战的前端学习者,我不知道这些说的对不对,但是这就是我个人的感受。学习React我认为在如今是必须,无论是你为了ReactNative的跨端带来的便利,还是为了阅读更多React,Next的优秀项目,React都是作为前端的必需品。在Ai时代下,学习一个框架变得更加的简单,不懂的知识能问Ai快速的获取,代码也从一定要能写出来,更加的倾向于能看懂,知道逻辑,技术栈的选择感觉也更偏向于Ai能不能把这个技术的代码给写好,毕竟现在都是Ai写代码。

使用社交账号登录

  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...