Loading...

在 React Hooks 的加持之下,Modern React Web App 有了不一樣的氣象,對於新入手的開發者來說,可以從最熟悉的 function 開始學起 React;對於熟悉 React 的開發者而言,則可以練習不受舊有思維的影響,感受 Hooks 帶來的簡潔與便利性。不論你是有經驗的 React 開發者,或是初入前端想要開始學習接觸前端框架的有志之士,就讓我們從 Hooks 開始,讓你的網頁 React 起來吧!

2019年2月,React 16.8 版開始正式支援 Hooks 的用法,熟悉 React 的開發者即使還沒自己用過,但一定聽過 Hooks 這個詞;對於原本 Vue 的開發者來說,在 Vue Function-based API RFC 中也試著把 React Hooks 中以「函式」來複用邏輯的概念放入 Vue 原本的框架中。

到底這個大家都在說的神奇鉤子(Hooks)是什麼?

(本文轉載自PJ的從 Hooks 開始,讓你的網頁 React 起來 ,本系列文章已出版成書「從 Hooks 開始,讓你的網頁 React 起來」)

在開始撰寫 React 之前,需要讓大家有一個比較統一的開發環境,如此可以避免因為作業系統、環境版本、React 版本的差異造成影響。一開始在專案還沒有很複雜前,我們會使用 Codepen 來練習基本的 React 概念,等到專案更複雜之後,我們會再使用其他開發工具。

註冊 CodePen 帳號

Codepen 這個工具很容易上手,其中一側可以編輯 HTML、CSS 和 JS,另一側會顯示對應的畫面。之後幾天我們會持續用 CodePen 進行練習,所以如果還沒註冊帳號的話,可以趕快來註冊一個:

Imgur

學習/複習 React 中一定會用到的 JavaScript 語法

進入到 React 的內容後,只會提供 JavaScript 語法的關鍵字讓大家進一步到 MDN 查找資料,因此趁著今天先來簡單學習/複習和 React 有關的 JavaScript 語法。

如果覺得今天的內容太多一時無法吸收也不用擔心,未來會實際把這些 JavaScript 語法應用在 React 的專案中,到時候在「使用關鍵字 + MDN」去查詢並學習理解即可:

Imgur

如果需要的話,你可以在 CodePen 中開啟一個新的 Pen 搭配練習,只需要把 JavaScript 語法撰寫在 JS 的區塊中,接著打開瀏覽器的 console 介面作為練習:


Imgur

像是這樣:

Imgur

樣板字面值(Template literals/Template strings)

「樣板字面值」方便我們可以直接在字串中帶入 JavaScript 表達式(expression),使用上只需要將原本字串的內容用反引號(鍵盤 1 左邊那個)包起來,需要帶入表達式的地方在使用 ${} 帶入即可。

實際的應用像是這樣:

也可以帶入其他表達式:

「表達式」簡單來說就是當你給它一段程式碼去執行後,它會直接回傳一個值給你。若還不太清楚 statements 和 expressions 的差異,可以參考 [筆記] 進一步談JavaScript中函式的建立─function statements and function expressions

箭頭函式(arrow functions)

箭頭函式是在 ES6 中另一種更簡便來定義函式的語法。傳統上我們會這樣定義 JavaScript 的函式:

在 ES6 中則可以用箭頭函式讓它變得更精簡。箭頭函式的使用會把函式的參數放在前面的小括號 () 中,中間搭配 =>,原本函式執行的內容則放在最後的大括號 {} 中:

如果在箭頭函式中只會回傳一個值而不需要做其他的操作的話,甚至可以精簡成這樣:

物件屬性名稱縮寫(Shorthand property names)

當物件的屬性值是一個變數,而屬性名稱又和該變數名稱相同時可以縮寫偷懶,寫出屬性名稱即可。什麼意思呢?來看下面這個例子。

首先定義了三個變數,分別是 deviceNamecurrentPricestorage,現在想要把這三個變數當成物件 galaxyNote 的屬性值,原本會這樣寫:

但由於物件的「屬性名稱」和當成屬性值的「變數名稱」相同,因此可以縮寫成這樣子:

解構賦值(Destructuring assignment)

解構賦值可以幫助我們用簡短的語法,從物件或陣列中取出所需要的資料,並建立成新的變數。

簡單來說,解構賦值讓開發者可以達到快速建立變數並取值的動作

物件的解構賦值

常見的情況時,當從伺服器拿到的資料是帶有一大包內容的物件,而我們只需要用到該物件裡面的其中一些屬性,這時就很適合使用解構賦值。

舉例來說,現在從伺服器拿到一大包和商品名稱有關的資料:

如果現在要建立新的變數,並在變數中代入該商品的名稱(name)和描述(description),傳統上可能會這樣做:

在使用物件的解構賦值之後,可以達到快速建立變數並取值的動作

進階:透過解構賦值取出物件中的物件

同時你可能好奇,像現在 product 物件中還有 offers 這個物件,如果要取得 offers 物件內的 price 一樣可以透過解構賦值取出嗎?

是可以的,寫法會像這樣,意思就是要定義一個名為 price 的變數,它的值會是 product.offers.price。但要注意的是,現在就沒有新增 offers 這個變數了:

如果同時需要建立 offersprice 這兩個變數,有時會這樣寫。先透過解構賦值先取出 offers,接著一樣透過解構賦值再從 offers 中取出 price

陣列的解構賦值

陣列同樣也有解構賦值的寫法,這在 React Hooks 中經常被使用。

直接看程式碼會比較清楚,假設伺服器回傳一個陣列中包含各種廠牌的智慧型手機,而且陣列中元素的順序是照當年度銷售排行:

如果想要取得當年度排行前三名的手機,並建立成變數,傳統上可能需要這樣寫:

這時同樣可以使用解構賦值來達到快速建立變數並取值的動作,陣列的解構賦值會依據陣列內元素的順序把值取出來,像是這樣:

展開語法和其餘語法(Spread Syntax/Rest Syntax)

最後一個同樣經常在 React 中會使用到的語法,稱作「展開語法(Spread Syntax)」和「其餘語法(Rest Syntax)」。這兩個語法的使用時機不同,但在寫程式時是用相同的文字來表達,也就是 ...。

沒錯,就是 ...,這個 ... 可以同樣可以使用於物件和陣列上。

展開語法(spread syntax)

展開語法最常用在要「複製一個物件,並為該物件添加一些屬性時」,舉例來說,我們先定義智慧型手機的基本屬性:

接下來如果要複製 mobilePhone 這個物件變成一個新的物件(iPhone),同時添加一些屬性時,可以使用 ... 展開語法:

這裡我們定義了一個新的物件,稱作 iPhone,接著把原本 mobilePhone 的內容全部複製一份進去,最後再添加 nameos 這兩個屬性進去。

可以注意到,在原本的 mobilePhone 就已經有 name 這個屬性,後來我們又添加同樣名為 name 的屬性時,就會把原本的 name 給覆蓋掉;而 os 這個屬性,因為在原本的 mobilePhone 中沒有這個屬性,所以就會直接被添加到新的 iPhone 這個物件內。

我習慣把「展開語法」的 ... 當作「解壓縮」的概念,就是把原本的物件,解開來,再放進去新的物件裡面,同時還可以添加一些新的屬性。

展開語法同樣可以用來複製陣列,並在新的陣列中添加元素,像是這樣:

其餘語法(rest syntax)

其餘語法和展開語法的寫法一樣,都是 ...,但是使用時機不太一樣,如果說展開語法像是「解壓縮」,那麼其餘語法就像是「壓縮」。它可以把在解構賦值中沒有被取出來的物件屬性或陣列元素都放到一個壓縮包裡。

舉例來說,在前面談到物件解構賦值的時候,從伺服器拿到一大包資料:

雖然我們取出了所需的資料,但其餘剩下沒有取出來的物件屬性仍想要取出來稍後使用,這時就可以使用其餘語法,把除了 namedescription 剩下沒有取出來的物件屬性,都放到取名為 other 的變數中(變數名稱可以自己取),如此 other 就會是 product 物件中,扣除掉 namedescription 屬性後的所有其餘資料:

其餘語法同樣可以用在陣列中,前面我們有把銷量前三名的手機取出來,那其餘剩下沒被取出來的怎麼辦呢?這時候就可以使用「其餘語法」把剩下的陣列元素全都拿出來,像是這樣:

這些 JavaScript 全都要會才能繼續看下去嗎

如果上面提到許多 JavaScript 語法,你都覺得非常陌生的話先不會擔心,因為如果你是第一次吸收這些語法的話,一次塞這麼多東西反而會很難吸收。建議可以等到後面開始實作 React 的時候,你一定還會看到這些語法,等到那時候再來慢慢搭配關鍵字到 MDN 查詢這些語法就可以了。

參考資源

【前端職涯升級】React 專案應用直播班:自主打造 React 專案,豐富你的作品集