A
約 4 分鐘閱讀

從 Vue 跳到 React 的開發心得 — 兩個框架的差異與轉換經驗

做前端這幾年,Vue 和 React 都有碰過。一開始是從 Vue 入門,後來工作上也接觸了 React 專案。這篇來分享一下在兩個框架之間轉換的心得,以及實際開發時感受到的差異。

為什麼要學 React

老實說,Vue 用得很順手的時候,一開始對學 React 沒有太大的動力。但後來發現幾個現實的考量:

  1. 工作機會:看職缺的時候,React 的需求量確實比 Vue 多,而且很多外商缺也都是用 React
  2. 生態系:React 的社群資源和第三方套件非常豐富
  3. 技術視野:多學一個框架可以用不同角度思考問題

而且 Vue 和 React 的核心概念其實很類似,轉換的門檻沒有想像中高,尤其是到了 Vue 3 時代,Composition API 的概念都和 React Hooks 很像。

最明顯的差異:模板 vs JSX

Vue 用的是 template 語法,長這樣,其實就是 HTML 加上 Vue 的指令(directives):

<template>
  <div>
    <h1>{{ title }}</h1>
    <ul>
      <li v-for="item in items" :key="item.id">
        {{ item.name }}
      </li>
    </ul>
    <button @click="handleClick">點我</button>
  </div>
</template>

React 用的是 JSX,邏輯和 UI 混在一起:

function MyComponent() {
  return (
    <div>
      <h1>{title}</h1>
      <ul>
        {items.map((item) => (
          <li key={item.id}>{item.name}</li>
        ))}
      </ul>
      <button onClick={handleClick}>點我</button>
    </div>
  );
}

剛開始看 JSX 會覺得很亂,怎麼 HTML 跟 JavaScript 攪在一起。但寫久了發現,這種寫法其實很靈活,複雜的條件渲染反而比 v-if 直覺。

仔細想想,React 本質上其實就是 JavaScript 加上 JSX 語法而已。它沒有像 Vue 那樣有額外的模板語法(v-ifv-forv-model),所有的邏輯都是用原生 JavaScript 來寫。這也是為什麼學 React 之前要先把 JavaScript 基礎打好——你需要熟悉 mapfilter、三元運算子、解構賦值這些東西,因為 React 就是拿這些來處理 UI 邏輯的。

狀態管理的差異

Vue 3 的 Composition API 和 React Hooks 其實很像:

Vue 3:

const count = ref(0);
const doubled = computed(() => count.value * 2);

const increment = () => {
  count.value++;
};

React:

const [count, setCount] = useState(0);
const doubled = useMemo(() => count * 2, [count]);

const increment = () => {
  setCount(count + 1);
};

主要差異是 Vue 的 ref 是響應式的,改值直接 .value = xxx。React 的 useState 要用 setter function,而且是不可變的(immutable)。

一開始常常忘記用 setCount,直接寫 count++,然後畫面就不會更新。這個習慣要適應一下。

生命週期的對應

Vue 和 React 的生命週期可以這樣對應:

Vue 3React
onMounteduseEffect(() => {}, [])
onUpdateduseEffect(() => {})
onUnmounteduseEffect 的 cleanup function
watchuseEffect 搭配 dependency array

React 把所有副作用都用 useEffect 來處理,一開始會覺得有點不直覺。但習慣之後,其實邏輯蠻清楚的——dependency array 決定什麼時候要重新執行。

詳細的生命週期對照與陷阱

很多從 Vue 轉過來的人(包含我)最容易在 useEffect 踩坑,因為我們習慣了 onMounted 這種「時間點」的思考模式,但 React 的 Hooks 是「狀態同步」的思考模式。

Vue (時間點思維)React (同步思維)常見心智模型落差
onMounteduseEffect(..., [])Vue 只跑一次;React 在 StrictMode 開發環境會跑兩次(這是正常的!)
watch(xx)useEffect(..., [xx])Vue 的 watch 預設是 lazy 的;UseEffect 在 render 完一定會至少跑一次
onUnmounteduseEffect return function容易忘記 cleanup,導致 event listener 重複綁定

最大的陷阱:Stale Closure

在 Vue 裡面,你在任何地方讀 count.value 拿到的都是最新的值。但在 React 的 useEffectuseCallback 裡,如果你沒把變數放進 dependency array,你讀到的會是「舊的」變數。

// React 陷阱題
useEffect(() => {
  const timer = setInterval(() => {
    console.log(count); // 這裡的 count 永遠是初始值 0!
  }, 1000);
  return () => clearInterval(timer);
}, []); // 因為 dependency 是空的

這真的要花點時間適應,Vue 的響應式系統太聰明了,幫我們處理掉很多這種底層問題。

心智模型的轉變:Mutable vs Immutable

這應該是兩個框架最核心的差異。

Vue 的世界觀:你可以修改我,我會通知大家。 Vue 的 data 是 mutable 的。你想改標題?title.value = 'New'。Vue 的 Reactivity system 會攔截這個 setter,然後去更新畫面。這很直覺,跟我們寫傳統 JS 物件導向一樣。

React 的世界觀:你不能修改我,你要創造一個新的我。 React 的 state 是 immutable 的。你想改標題?你不能改舊的 title,你要呼叫 setTitle('New'),這會告訴 React:「嘿,用這個新值重新畫一次 component」。

這個差異導致了寫 code 習慣的不同:

習慣 React 的 Immutable 模式後,你會發現 data flow 變得很容易預測。因為資料不會莫名其妙被改掉,一定是有某個 setXXX 被呼叫了。這在大型專案除錯時非常有幫助。

Next.js vs Nuxt

如果要做 SSR,Vue 有 Nuxt,React 有 Next.js。兩個框架的概念很類似:

用過 Nuxt 3 再去學 Next.js,上手很快。主要差異在一些 API 命名和寫法上。

資料抓取:

Nuxt 用 useFetchuseAsyncData

const { data } = await useFetch("/api/posts");

Next.js 的 App Router 用 async component:

async function Page() {
  const data = await fetch("/api/posts");
  return <div>{/* ... */}</div>;
}

狀態管理工具

Vue 生態系用 Pinia,React 生態系選擇比較多:Redux、Zustand、Jotai、Recoil…

我自己比較喜歡 Zustand,寫法簡潔,跟 Pinia 的感覺有點像:

// Zustand
const useStore = create((set) => ({
  count: 0,
  increment: () => set((state) => ({ count: state.count + 1 })),
}));

// 使用
const { count, increment } = useStore();

比起 Redux 的 action、reducer、dispatch 那一套,Zustand 直接多了。

轉換時遇到的坑

1. 忘記 Immutable

React 的狀態更新要保持 immutable,不能直接修改原物件:

// ❌ 錯誤
const handleClick = () => {
  items.push(newItem);
  setItems(items); // 不會觸發更新
};

// ✅ 正確
const handleClick = () => {
  setItems([...items, newItem]);
};

Vue 的響應式系統會幫你處理這些,React 要自己注意。

2. useEffect 的 Dependency Array

useEffect 的 dependency array 設錯,會造成無限迴圈或該更新的時候沒更新:

// ⚠️ 小心無限迴圈
useEffect(() => {
  setCount(count + 1);
}, [count]); // count 變了就執行,執行又改 count...

3. Conditional Hooks

React Hooks 不能放在條件式裡面:

// ❌ 錯誤
if (isLoggedIn) {
  const [user, setUser] = useState(null);
}

// ✅ 正確
const [user, setUser] = useState(null);
if (isLoggedIn) {
  // 使用 user
}

這個規則一開始會覺得很奇怪,但這是 React Hooks 的設計限制。

哪個比較好?

這個問題沒有標準答案。兩個框架都很成熟,都能做出好的產品。

Vue 的優點:

React 的優點:

我自己是兩個都用,看專案需求決定。已經有 Vue 基礎的人,學 React 不會太困難,反過來也是。

給想學 React 的 Vue 開發者

  1. 先學好 JavaScript:React 比較需要紮實的 JS 基礎,特別是 array methods、解構、spread operator

  2. 接受 JSX:一開始會不習慣,但寫久了會發現它的好

  3. 理解 Immutable:這是 React 的核心觀念,一定要搞懂

  4. 不要硬套 Vue 思維:有些東西在 Vue 很自然,在 React 要換一種方式思考

  5. 從 Next.js 開始也行:如果已經會 Nuxt,直接學 Next.js 會很有帶入感,學得也快

結語

Vue 和 React 都是很棒的框架,沒有誰比較好的問題。多學一個框架可以拓展視野,也能增加求職的競爭力。

如果你跟我一樣是 Vue 起家的,不用怕學 React。核心概念很類似,主要是語法和一些設計理念的差異。適應期過了之後,就能兩邊都寫了。


站內相關文章: