# 從Native到React:初學React.js角度的JavaScript「升級」整理 ###### tags: `React` `前端框架` `心得` `JavaScript` `語法` ## 前言 - **學習目標:整理React.js(17)作為前端框架,與Native JS相比增加的常用概念** - 概念建立後,實作的部分再查文件(沒有概念的話,看不懂甚至不知道要查什麼文件) - *~~因為不喜歡Vue的模板與專有語法,覺得很不JS想跳槽~~* - 算是給自己看的讀書筆記、重點整理 - 也可以一邊思考新技術是為了解決那些既有問題 - *~~有餘力的話再整理個Vue3的版本~~* - 簡述React的**特色:用JavaScript的思維與格式處理前端的渲染** - 主要的HTML內容改寫在.js檔案(雖然實際格式為[JSX](https://zh-hant.reactjs.org/docs/introducing-jsx.html)),甚至CSS也能選用JS管理 - 只需要一個.html檔案,除了`<head>`的設定,`<body>`只需要`<div id="root"></div>`給React渲染用 - 使用[Virtual DOM的概念](https://ithelp.ithome.com.tw/articles/10234155)一次性的渲染,而非每次個別操作DOM - 多一些非原生的語法(如[render](https://zh-hant.reactjs.org/docs/rendering-elements.html)),*但看起來風格至少很JS(如和Vue相比?)* - 因為都放在JS處理,有些原生的寫法得改掉(如避免與保留的關鍵字衝突、符合JS的coding style常規) - 主要參考資料: - 可先看先前整理的[入門篇筆記](https://hackmd.io/@BOBYZH/B1xoUGw9F) 1. [**React繁體中文官網**](https://zh-hant.reactjs.org) - 有完整文檔和示範教學,但更適合當文件查詢 - 示範教學因為用的是舊的class component,要跟著做的話較推薦下一本書的範例 2. [**從Hooks開始, 讓你的網頁React起來(2020)**](https://one.ebook.hyread.com.tw/bookDetail.jsp?id=226978) - 改編自[鐵人賽系列文章](https://ithelp.ithome.com.tw/users/20103315/ironman/2668),有JS基礎就能讀懂 - 以**專案進度逐步引導**用到的React概念(**初學者**推薦) 3. [**React思考模式:從hook入門到開發實戰(2021)**](https://one.ebook.hyread.com.tw/bookDetail.jsp?id=261452) - 介紹的React功能相對前者較多,且解釋較多運作的原理(需較多先備知識+論述可能較抽象?) - **補上前一本書最後只是帶到沒有細述的部分**,但因為後半較複雜,初次讀先大概看過即可(**需實作時再查**套件文件比較好用) 4. 之前參與協作React.js與[React Native](https://reactnative.cn/)(RN,[二者簡易轉換心得](https://hackmd.io/@BOBYZH/B1NpYzKlq))專案經驗 - 補充在本文的個人觀點 ## 基礎部分 - 以網頁組成三大元素,個別簡易說明在React多了哪些變動 - 如果是RN,**得使用專為RN設計的語法和套件** - 寫的不是HTML和CSS,容易出現WEB沒有的概念 - 加上兼顧不同平台效果(Android、iOS...)的話還有個別設定 ### 基礎安裝設定 - 簡易版(練習,CDN) - 在HTML引入"react"(核心邏輯)、"react-dom"(操作WEB)、"babel"(編譯使用JSX語法)的`<scrpt>`標籤 - 推薦配合[codepen](https://codepen.io/topic/react/templates)、[jsbin](https://jsbin.com/?html,js,output)、[repl.it](https://replit.com/)等線上簡易IDE使用 - 複雜版(開發,NPM) - 新建專案時建議用如[Create React App](https://zh-hant.reactjs.org/docs/create-a-new-react-app.html#create-react-app)等工具產生 - 已有基本套件、結構與設定的專案,改起來比較快 - RN:請從[環境建置](https://reactnative.cn/docs/environment-setup)開始 ### HTML:寫法的變化(微調的概念?) 寫的其實是JSX而非純HTML(JSX語法其實非React專用,[Vue也可以用](https://staging-cn.vuejs.org/guide/extras/render-function.html#render-functions-jsx)) - **class => className**(與JS保留的關鍵字衝突) - **表單**(form)如input、textarea、select中value屬性概念的變化 - value - 在React中,值可以選用狀態(state)管理 - 新屬性**defaultValue**:輸入欄位只有一開始受狀態影響的初始值 - 既有寫法:欄位數值一直受狀態管理(不像純HTML只定義初始值) - checked - 可用回傳布林值設定 - **kebab case => camel case** - 寫法習慣,如在JS寫CSS/RN的style,否則噴錯誤 - 一些原本沒用kebab的也要改camel,如onclick => on**C**lick - [onClick載入函式的寫法有有區別](https://zh-hant.reactjs.org/docs/handling-events.html) - html作為特殊資料類型而非字串)(render()使用) - `"<div></div>"` => `<div></div>` - **component(元件/組件,格式:`<Component />`或`<Component>...</ Component>`)** - 大寫開頭,以和一般的HTML作區別 - 除了自己寫,也可以引入套件(再參考文件說明的屬性使用) - 使用[**Design System (設計系統)](https://5xruby.tw/posts/react-design-systems)**:如Ant Design、Material UI...,比bootstrap更進階的懶人救星(X) - 最外層一定要包一個Tag - 僅包覆不含語意的寫法:Fragment(`<></>`) - **只要大概了解JSX與純HTML的差別部分,以及有component的概念,即使沒學過React才有的JS語法,就能以既有的概念切版,甚至多少看懂functional component 的用途(個人想法)** - 略懂就能寫React(X)可以協助較簡單的部分(O) ### CSS:格式的選擇性(不一定要大改) 格式可以和純靜態檔案一樣,或加上JS擴充大改 - **主要考量:分拆管理、避免全域衝突...** - **可考慮用原生CSS以外的工具,以加入更多程式邏輯要素(如嵌套、變數、運算):** - [常見工具方案與原生寫法的簡易比較](https://segmentfault.com/a/1190000039824670) - CSS預處理器(CSS preprocessor) - 如Sass、Less... - 與原生CSS寫法基本相容 - 需額外設定才能使用 - CSS Modules - 簡言之,全域和頁面載入各自的CSS - 說明[可參考這篇](https://ithelp.ithome.com.tw/articles/10279072) - 增加的功能相對少 - CSS in JS - 如styled-components、emotion... - 簡介[可參考這篇](https://juejin.cn/post/6935245880568053791) - 與原生CSS寫法差異較多 ### Script - 1:加入React才有的常見概念 基本符合JS風格下,新增若干概念和語法 - **`render()`**:頁面用JS設定後才一起渲染,而非個別修改DOM - **key**:辨認同類元件的索引,重複渲染元件時若沒設定會跳警告 - `${}` vs `{}` / `{{}}` - `${}`:原生語法的[樣板字面值/模版字符串(template literal)](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Template_literals) - `{}`:填React props帶入的資料,或是條件轉譯的判斷式(表達/表示式,expression,有回傳值的邏輯運算做為顯示資料) - 例如切換視圖:{currentPage === 'SomePage' && (<Component />)} - `{{}}`:填寫CSS/Style屬性(作為物件放到前者的概念) - **function components** - 語法特點 - 以函式(function)形式定義參數屬性與回傳的HTML內容 - 主要取代2019年前較複雜的class components - 也替代處理資料與畫面對應變動的原生語法(querySelector或getElementByClass/Id後修改DOM) - 也有生命週期(lifecycle)的概念(類似Vue) - 分3(+1)階段:初始化/創建/掛載(mounting)、更新(updating)、移除/銷毀/卸載(unmounting),(以及JS噴錯的Error Handling) - 在class components比較重要,function components較少直接用到 - (個別週期的細節太多人介紹,自行找幾篇來看即可) - **props(概念)** - 引入父層的資料(父傳子) - 父層資料變動時,子層元件也會重新轉譯(更新資料渲染) - 如同一般函式,需有引入/回傳相關的值 - 可使用解構賦值來接收(如參數填入`{value}`) - 如果元件層次較多(二三層以上),甚至有傳給同層甚至父層的需求,有Global state的概念比較方便(類似全域變數?) - **Context(概念)** - Global state在React的實作方案 - 建立全域資料:`React.createContext()` - 產生物件,可獨立成外部模組檔案引用(如放context資料夾) - 使用全域資料:`<XxxContext.Provider>` - 以元件形式引入,屬性加上`value={{context檔案的物件資料/動作格式: 要讓全域使用的變數資料/動作名稱}}`(搭配useState) - 在其他地方使用時,需要使用useContext這個hook - 數值更新時,有引入的元件會強制渲染(可能影響效能) - **Hooks(常用)** - 格式:`useSomething` - 其實也算JS的函式(function) - 在元件內處理資料常用:使畫面變更/變更後執行 - 通常不會在迴圈、條件判斷、槽狀結構等「不一定會執行到」的情況使用 - 最常用於資料存取的hooks - **useState(狀態):定義資料預設內容(`value`)與修改動作**(`setValue`) - 常以解構賦值定義(如`const [value, setValue] = useState("default")`) - **代替使用變數`var/let`的原生寫法來管理** - 檢查到狀態變更後重新渲染DOM - 資料與畫面需透過`setValue`的形式修改與渲染,否則無效或噴錯誤(不要用原生的變數寫法來處理,可能值改了但畫面沒改) - 會一次覆蓋全部,只改部分需加入`...value`保留其他資料 - 函式呼叫後其實不會馬上修改state,需要立即接續其他動作的話要用下面的useEffect - **useEffect(副作用):畫面渲染後才執行的動作** - 第一個參數,用來定義在畫面更動後的函式,例如: - 呼叫API存取遠端資料(避免非同步事件阻塞,回傳後再替代載入圖示) - 外來可能有專門的[suspense](https://reactjs.org/docs/concurrent-mode-suspense.html)來處理 - 使用非React專用的外部函式庫(避免衝突) - 操作DOM、動畫(避免在前面HTML尚未生成) - add/removeEventListener(建立時add,第一個參數回傳時remove避免重複監聽) - set/clearInterval(原理同上) - 第二個參數,須定義dependencies,可避免陷入更新資料後,又因畫面隨資料變動陷入迴圈(如用空陣列表沒有要觀察的變動) - 未定義時,元件建立與每次更新都觸發 - 定義空陣列時,元件建立時才觸發 - 若第一個參數的副作用定義區,使用了沒在第二個相依參數的props/state,會有非預期錯誤 - **存取不受React管理的部分** - useRef:定義的變數可類比直接用原生語法操作DOM元素,而不出現錯誤或React更新渲染 - 括號放預設值,在元件的ref屬性填入使用 - 可用在不需保存狀態的變數、操作特定DOM(新增或移除函式)、用狀態管理可能額外動作的情況(如計數counter、有設定effect副作用) - 如存放不觸發畫面元件更新的變數 - [和直接定義全域變數的差別:後者會在重新渲染時更新,導致數值不如預期](https://stackoverflow.com/questions/57444154/why-need-useref-and-not-mutable-variable) - 介於被React管與不管之間(?) ## 進階部分 - [參見後半筆記](https://hackmd.io/@BOBYZH/HJpJHcs-5)
×
Sign in
Email
Password
Forgot password
or
Sign in via Google
Sign in via Facebook
Sign in via X(Twitter)
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
Continue with a different method
New to HackMD?
Sign up
By signing in, you agree to our
terms of service
.