## React 筆記 ### Component-based Design (元件導向) React 函式庫提供 **Component 類別** 讓工程師以繼承 **(extends)** 此模板方式進行網頁開發,此元件可以重複使用,<font color='blue'>透過 override (覆寫) **生命週期函式** 的界面來執行 UI 互動、網路存取、資料變更...等其他程式流程</font>,資料流為 **單向資料流**,父元件資料可層層傳遞給子元件。 React Component 有兩種方式可以取得資料,(父元件)從外部傳入資料會保存於 **props** 名稱之變數,內部資料保存於 **state** 名稱之變數。 內部僅 **<font color='orange'>render()</font>** 方法為必要,其餘方法非必要。 - **stateful vs stateless** > 1. **stateful 元件**:內部帶有 state 變數的元件。 > 2. **stateless 元件**:內部不帶有 state 變數的元件。 - **controlled vs uncontrolled** > 1. **controlled 元件**:資料狀態保存於 **state** 上。 > 2. **uncontrolled 元件**:資料狀態保存於 **DOM 元素** 或是 **refs(RefObject)** 上。 ### Life Cycle(生命週期) 主要分為三大週期:**Mounting、Updating、Unmounting**。(下圖為 v16.4 以上)  - **Mounting 階段** 當一個 component 的實例(instance) 初次被建立且加入 Virtual DOM 中時,其生命週期將會依照下列的順序呼叫這些方法: :::info 1. <font color='orange'>**constructor()**</font> - 初始 state。 - 綁定函式,如 ```javascript! this.handleClick = this.handleClick.bind(this); ``` - 若無初始或綁定動作,則可 **不需要** 覆寫建構子。 3. <font color='orange'>**render()**</font> 4. <font color='orange'>**componentDidMount()**</font>: 於掛載後僅 **執行一次**。 ::: - **Updating 階段** 當 props 或 state 有變化 或 強制更新 時,就會 **觸發更新階段**。當一個 component 被重新 render 時,其生命週期將會依照下列的順序呼叫這些方法: :::info 1. **static** getDerivedStateFromProps(**nextProps**, prevState) - 此為 **類別函式**,掛載與更新兩個階段皆會被執行。 - 當 props 變動、setState() 或是 forceUpdate() 就會被觸發。**(>=v16.4)** 只有 props 變動才會被觸發。**(v16.3以下)** - 回傳 null 時表示不更新 state,若回傳一個物件則更新 state。 - 可取代即將廢棄 **componentWillReceiveProps()**。 3. <font color='blue'>**shouldComponentUpdate()**</font> 4. <font color='orange'>**render()**</font> 5. getSnapshotBeforeUpdate(prevProps, prevState) - 可以透過傳入參數訪問 DOM 更新前的 **props 與 state**,作為快照傳給 componentDidUpdate()。 - 回傳值可當作參數傳給下一個函式 componentDidUpdate() 的第三個參數。 - <font color='red'>注意! 必定要與 **componentDidUpdate()** 搭配一起使用,否則編譯時會報錯!(有 4,則 5 一定要覆寫)</font> 7. <font color='orange'>**componentDidUpdate(prevProps, prevState, snapshot)**</font> ::: - **Unmounting 階段** 當一個 component 從 Virtual DOM 中被移除時,這個方法將會被呼叫: :::info 1. <font color='orange'>**componentWillUnmount()**</font> 用於 **註銷或解除** 元件銷毀後將不再使用的事件或資源。 ::: ### Virtual DOM Virtual DOM 是通過 JavaScript 物件儲存在記憶體中,模擬真實 DOM 的方法。不只是 React,其他框架(Vue)也有 Virtual DOM 的應用。 :::success :bulb: Virtual DOM is a **lightweight copy and virtual representation** of the actual DOM. It is also <font color='orange'>**an abstraction**</font> of the HTML DOM. ::: #### DOM Diff 當 DOM 的節點需要更動時,不會直接修改 DOM,而是透過 DOM diff 演算法 **比較 Virtual DOM** 修改前與修改後的樹狀結構,再批次更新真實的 DOM 節點。  #### 解決效能問題 直接操作 DOM 雖然快速、方便,但是瀏覽器所耗費的成本極大,故 <font color='orange'>**在頻繁操作 DOM**</font> 的情境下則會導致瀏覽器效能低下甚至畫面卡頓,因此透過 Virtual DOM 可優化效能。 (不會只因為<font color='red'>**連續改一個小節點**</font>,而一直遍歷整個 Tree,造成效能低下) ### 參數傳遞 - **父元件向子元件傳遞** 透過 props 參數傳遞,遵循『單向資料流』方向,不能反向傳遞。 :::success :bulb: **Props Drilling** 多層嵌套的元件,則會發生 **Props Drilling 問題**,即 <font color="red">中間組件必定會被**傳遞參數**探鑽</font>,造成元件不易維護的問題 ::: - **子元件向父元件傳遞** 子元件可以透過 **callback 回調函式** 向父元件傳遞子元件的內部資料。 - **向其他元件傳遞** - React 本身提供 **Context API 來分享狀態**,亦可提供局部共享範圍(可包在大型、複雜的組件下限定共享範圍),可與第三方管理工具靈活搭配。 - 第三方狀態管理工具,常見有:Redux、MobX、DvaJS ... 等。 :::success :bulb: DvaJS 是一套基於 **Redux 與 Redux-saga 的資料流解決方案**,為了簡化開發流程,亦內建 react-router 與 fetch,可視為一個輕量級的框架了。 **DvaJS 框架**  ::: ### 參考網址 1. [React.Component](https://zh-hant.legacy.reactjs.org/docs/react-component.html) 2. [請解釋 React 生命週期?]( https://www.explainthis.io/zh-hant/swe/react-lifecycle) 3. [什麼是 Virtual DOM?](https://www.explainthis.io/zh-hant/swe/react-virtual-dom) 4. [Virtual DOM & DOM Diff]( https://tutorialslink.com/Articles/What-is-Virtual-DOM/1580) 5. [React 生命週期圖示](https://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/)
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up