iT邦幫忙

2022 iThome 鐵人賽

DAY 5
0
Modern Web

前端技能樹的十萬個為什麼系列 第 5

Day 5 - 為什麼要用 React

  • 分享至 

  • xImage
  •  

前言

React 是許多前端工程師賴以謀生的工具,我當時就是跟隨著時代洪流,從 jQuery 跳到了很多人討論的 React。

捫心自問,其實我真的沒有很了解它,只是因為大家都在用就學了(掩面),所以藉著這個機會,我們用幾天的時間來了解 React 到底是什麼。

先想一下

  • React 是在什麼樣的時代誕生的?
  • React 怎麼解決問題?
  • React 的優缺點是什麼?
  • React 適合什麼情境?

React 是在什麼樣的時代誕生的?

每個技術、工具都有誕生的理由,不然 jQuery 當初用得好好的,沒事不需要再多寫一個 React 出來。

但從 Day 2 的討論可以看到,隨著前端的規模越來越大,複雜性愈來愈高,每當資料變動需要更新畫面時,jQuery 雖然提供了很直覺的操作介面,比如 .show().hide() 就能做到元件顯示隱藏,但這樣是比較偏向 imperative (命令式) 的寫法,講白了就是說一步做一步,對於大規模的程式架構來說,這樣命令式的寫法容易讓一切變得複雜。

需要一種手法讓複雜的操作變得簡單一些,因此有名的「前端御三家」(React、Vue、Angular)就在那個時代漸漸地,成為新一代的前端熱門選項。

以下是透過 npm trend 劃出來的比對圖,可以見到 React 是什麼時候起飛的,也可以從這邊點進去看看哦:

React 怎麼解決問題?

React 是用來實作使用者介面的 JavaScript 「函式庫」,如同昨天討論到的,單論 React 本身,其實只是函式庫,除非加上 React 的生態系們,才比較說得上是 framework。

與 imperative (命令式)相對的,React 這套函式庫採用的是 declarative (宣告式) 的寫法,兩種都可以寫出程式,它們之間的差異是:

  • imperative 更關注在 HOW,也就是「如何做」,重視具體的每一步實作細節
  • declarative 更關注在 WHAT,也就是「要做什麼」,直接告訴程式我要的結果,讓程式自行判斷該如何達成,我只管結果

這邊聽起來會覺得很神奇,程式設計師不就是負責寫每一行 code,告訴程式具體的細節嗎?怎麼有辦法「只告訴結果」呢?難道我可以告訴 React 「我要一個登入功能」這樣嗎?

雖然沒有那麼神奇,但這邊就要帶到開頭提到的,React 是專注在「使用者介面」的 library,也就是 Day 3 提到的 MVC 中的 View 的部分

JSX

React 提供的 API 能夠讓開發者使用 JSX 的語法糖寫法,比如下面這個例子:

const element = (
  <h1 className="blue-color">
    Hello, World!
  </h1>
);

其實是個語法糖,會被轉換成下列這樣:

const element = React.createElement(
  'h1',
  {className: 'blue-color'},
  'Hello, World!'
);

也因此我們可以寫出類似這樣的東西:

const isRed = true;
const titleClassName = isRed ? "red-color" : "blue-color";
const element = (
  <h1 className={titleClassName}>
    Hello, World!
  </h1>
);

以上面的例子來看,如果要更改 class,我們不再需要用 jQuery 的方式(抓到 h1 element -> 修改 class),而是透過修改資料(titleClassName),自動地將資料的改變呈現在畫面上

而這就是所謂的 declarative,我們只有在資料上面宣告,實際上的畫面如何呈現,是由 React 負責。

其實這部分還牽涉到 MVVM 的概念,以及 React 的單向資料流特性,不過今天只打算討論「為什麼要用」,所以就不多細節說明了。

講到 DOM,這邊也要提到另一個概念 - Virtual DOM

Virtual DOM

在 jQuery 的時代,我們很習慣直接操作 DOM,針對 DOM element 去做一些 show/hide、append、class/style modification 等動作,但每一行都會讓 DOM 重新 render (依據修改的部分,可細分為 repaint 與 reflow),有時只是其中幾個節點的變化,卻需要瀏覽器背後大量的運算,其實是很不划算,也會拖慢效能的

因此 React 實作了一個介於真實 DOM 與資料之間緩衝層,也就是 Virtual DOM,它的步驟流程如下:

  1. React 會先複製一份 DOM 的物件(即為 Virtual DOM)
  2. Virtual DOM 其實就是一個 JavaScript 物件,目的在「描述」真實的 DOM 要長怎樣,物件內的每一個節點都會對應真實 DOM 的節點
  3. 當 React component 的 state 改變時,會比對先前的 Virtual DOM 和當前的 Virtual DOM 差異
  4. 算出實際需要更新的部分之後,再去更新真實的 DOM,有效減少 render 的次數,提高效能

因此,有了 Virtual DOM,開發者也不需要去擔心效能方面的問題,React 會自動幫我們比對出,要怎麼更新 DOM 最划算!

React 的優缺點是什麼?

優點

  • 宣告式更容易預測程式的行為,同時也較為容易除錯
  • 揉合多個 setState,合併為一次的操作,可以避免頻繁 render
  • 開發者可以專注在資料邏輯上,而不需要處理「資料 -> 畫面」這段過程

缺點

JSX 的寫法其實跟以前的寫法背道而馳,以前都會說要 HTML、CSS、JavaScript 分開,尤其不要讓 HTML 畫面跟 JavaScript 資料邏輯混在一起,結果現在 JSX 卻是這樣實作。

關於這點,React 官方給出的答案是:

關注點分離的方法是將其拆分為很多同時包含 UI 與邏輯的 component,而彼此之間很少互相依賴。

也就是回到 Day 3 提到的,關注點分離沒有一定正確的切法,React 提供了另一種切法,會將 HTML、CSS、JavaScript 揉在一起變成一個元件,但相對地,元件與元件之間就是獨立分離的。

因此這其實不能說是一個缺點,而是對於抱持 HTML、CSS、JavaScript 分離想法的人來說,React JSX 的寫法是需要花一點時間適應的

React 適合什麼情境?

相比 jQuery,React 從元件的角度,幫忙處理掉資料與畫面之間的同步,並且透過 Virtual DOM 自動運算出高效率的更新方式,面對規模愈大的程式架構,愈能夠看出 React 在這一方面的差異

結語

心智圖放大版

其實寫一寫會覺得,其實這篇比較像是在討論 jQuery 與現在所謂前端「框架」的差別,而不是針對 React,比如 Virtual DOM 其實在 Vue 也有類似的概念,只是因為我只會寫 React,所以就拿它來研究囉!

參考資料

React JSX
Virtual DOM and Internals
理解React Virtual DOM


上一篇
Day 4 - 為什麼要用 Framework(框架)
下一篇
Day 6 - 為什麼要用 React Hooks
系列文
前端技能樹的十萬個為什麼30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

1
Zet
iT邦新手 2 級 ‧ 2022-10-15 13:01:04

React 會先複製一份 DOM 的物件(即為 Virtual DOM)

這是一種蠻常見的誤解,實際上 React 是先自行以 Virtual DOM 來定義預計想要的畫面結構,然後再將這個結構的描述轉換成真實的 DOM Tree(也就是去操作真實 DOM Tree 來同步為長得跟 Virtual DOM 對應一致)。因此,這兩者之間的同步關係應該是由 Virtual DOM => DOM 單向的才對。開發者對 Virtual DOM 進行管理與互動,而由 Virtual DOM 到真實 DOM 的同步則由程式自動處理。

詳細可以參考這篇:https://ithelp.ithome.com.tw/articles/10293802

ycchiuuuu iT邦新手 4 級 ‧ 2022-10-24 13:59:30 檢舉

感謝大大幫忙勘誤!已修正原文

不得不說 Virtual DOM 的世界真的相當廣大。。。

我要留言

立即登入留言