近期看了一些新東西,有些觀念沒弄清楚,所以整個翻新之前的React新手系列文章。
這篇入門主要是跟著React官方文件和Udemy課程去整理和撰寫的。
一開始看到 React 很認真地在想為什麼需要它?但是當自己開始試做幾個side project,不斷在不同份檔案重複貼上相同的標籤或程式碼的時候,才認真體會到需要學習 React 的好處。總之入手新東西總是要有一點時間把玩和紀錄,所以出現了這篇系列文!
React 簡介
React由Facebook開發,是一個非常熱門的 JavaScript UI Library。雖然網路通常都會把React和 Vue、Angular 合稱三大框架,但React只處理UI(user interface),所以精確地說應該是library。
目前React有幾個讓大家愛不釋手的重要特性:state、component 和 hook,可以幫助我們便利又快速地建構出網站介面。
不過這篇只會先粗淺地提到state和component,因為React的架構基本上是由state和components組成。
為什麼需要 state 和 component?
試想一下今天要寫一個有100個分頁的網站,每個頁面可能需要根據不同資訊,顯示長相相似、只是資訊不同的彈窗,當使用者點擊到頁面某些按鈕或做了某些動作就會顯示這樣的彈窗。
好景不常,某天上司要求對這個彈窗增加一些限制,譬如哪些使用者才會看到彈窗,或是哪些使用者只看到部分資訊。假設今天只用純HTML和JavaScript編寫,就有可能需要對100個分頁去修改彈窗顯示的時機和資訊,或者更精確地來說「新增、修改或刪除彈窗顯示的時機和資訊」,而原來寫的JavaScript程式碼只是為了修改資訊,可能就會重複幾百次DOM操作等動作。
而React能做到的就是,開發者事先將彈窗程式碼用component和其包含的state包裝好,只要彈窗component的State改變,彈窗component的顯示時機或資訊就會跟著改變,不用只是為了修改彈窗的資訊而去一遍又一遍地重複操作DOM。
小結一下,為什麼需要 state 和 component?
Component 的好處在於可以包裝所寫的程式碼,並且能夠重複利用;而 state 則是用來驅動component更新(re-evaluate),並且根據修改的地方重新渲染(re-render)畫面。
因為這篇只打算簡單說明state和component在React扮演的角色,到這裡可能還會對state和component的概念有點模糊。
總之,只要記得state和component就是React用來處理使用者畫面/介面(user interface,UI)的兩個重要利器,細節則留到後面幾篇再討論。
開始寫 React 之前
開始寫React之前有以下幾個須知要留意一下,
- JavaScript 先備知識
- React 環境架設
- JSX
- camelCase 和 className
- Render: 如何在
.html
呈現 React 寫出來的HTML元素? - React DevTools extension
JavaScript 先備知識
React 是 JavaSciprt 的 Library,因此多少要有一些JavaScript的語法概念,同時React官方文件也有提到,至少要瞭解 function
、object
、arrays
和一些 classes
,以及ES6的 arrow functions
、let
、 const
和 destructure
(解構)。
React 環境架設
環境架設可分為線上(Online IDE)和離線:
線上版
如果只是練習可以先用一些線上開發工具來試寫React,官方文件是用CodePan,但我個人是喜歡CodeSandbox,CodeSandBox的免費版就能整合多個HTML、CSS和JavaScript檔案為一個專案,而且套用React專案模板就有內建的React DevTools(React開發者用可以幫助除錯的工具),不必自行在瀏覽器安裝擴充套件。
離線版
電腦需要先安裝Node.js,而且要確保Node的版本至少14.0.0以上,npm的版本至少5.6以上。
安裝好之後,選擇電腦中一個存放位置,可以使用任何command line介面輸入以下指令,其中的 my-app
為react專案名稱,可任意自行輸入喜歡的專案名字。
npx create-react-app my-app // 創建一個React專案,專案名稱為 my-app
cd react專案名稱 // 會看到一個和my-app同名的資料夾,這步是要進入資料夾
npm start // 啟動 React
create-react-app
一般是 React 用來創建基本款網站的指令,如果是要 server-side rendered website 或建立Gatsby等要用其他指令來創建React專案,詳情可參考👉官方文件
JSX
JSX 全名是 JavaScript eXtension。
React創建HTML元素的原理比較複雜,但React裡面的JSX可以讓我們用類似HTML標籤語法快速地寫出一個網頁,例如下方程式碼的 <h1>Nobody says hello!</h1>
。
另外,JSX也能使用大括號包住JavaScript的語法 { /*write JavaScript syntax inside it*/ }
就能方便地在任何地方使用JavaScript動態產生資料,例如 <h1>{name} says hello!</h1>
這段,當function sayHello的參數name有接收到一個引數 Lun 時,就能動態地根據name引數值產生 Lun says hello!
。
要注意的是,如果沒有加上大括號,例如註解掉的 <h1>name says hello!</h1>;
,產生的結果就會是「name says hello!」,而不會根據引數值改變 name。
function sayHello(name){
if(name === null) {
return <h1>Nobody says hello!</h1>;
}
else {
// return <h1>name says hello!</h1>; // error
return <h1>{name} says hello!</h1>;
}
}
alert(sayHello(Lun));
camelCase
JSX 可以用類似HTML標籤語言寫網頁,所以也能加上一些常見的HTML屬性,甚至是用JavaScipt物件包裝CSS的元素屬性語法來呈現網頁的畫面。
但有件非常需要注意的事情是,CSS會用 -
來命名一些屬性,如 font-size、background-color等;但JavaScript本身已經保留 -
作為算術運算用的減號,所以原來在HTML和CSS有用 -
命名的屬性必須改成 (lower) camelCase的寫法,例如下方JSX程式碼使用JavaScript物件儲存元素的CSS屬性,其中 font-size 要改成 fontSize
、background-color改成 backgroundColor
等。
let styledCSS= {
fontSize: "1rem",
color: "red",
backgroundColor: "black"
};
再來,因為JavaScript的class也是保留字(reserved word),因此原來在HTML標籤會用到class屬性的地方就需要改成 className
,例如 <h1 className="redTitle">Hello</h1>
。
此外,原本在JavaScript也有的onclick屬性,也統一成 onClick
;label標籤的for則要記得改成 htmlFor
。
如何在 .html
呈現 React 寫出來的HTML元素?
先從JavaScipt如何操作HTML元素物件的角度來切入,當我們使用JavaScript產生一個新的HTML元素後,最後都會有個的步驟,就是必須先取得HTML文件某個父元素(parent element),然後附加新產生的元素到這個父元素成為它的子元素(child element)。
同理,React 基本上也是用 JavaScript 產生新的HTML元素,這邊只概要說明React 如何將這些新元素 渲染(render) (或者理解為 附加 ) 在HTML文件上面。
如下圖,我們使用JSX語法包裝一個像是HTML標籤的React元素 <Game/>
後,同樣需要一份 index.html
檔案,並且加入一個為 根節點 的HTML標籤,然後用 document.getElementById("root")
取得id屬性為root的根節點標籤作為父元素,再用 ReactDOM.render()
渲染新的元素到這個父元素上。
不過這裡要注意的是,React在重新渲染的步驟並非根據資料的改變就直接操作DOM,而是先用React自己的virtual DOM,透過演算法比較畫面在資料改變前後有哪些地方需要更新,然後再將要更新的地方套用在真正的瀏覽器DOM,以減少直接操作瀏覽器DOM的巨大成本。
React DevTools extension
最後是介紹方便的 React 開發者工具可以幫助我們了解現在React 元素物件的模型架構、有哪些Components、各個Component的屬性和狀態值等,可根據所使用的瀏覽器,點選連結下載擴充套件:
以上只是記錄寫React以前應該要知道的一些事情,如何運用這些工具或語法可以再參考官方文件或其他資料!
References