React
https://pbs.twimg.com/media/GNNZGf1bIAAMl7u.png
React的特徵
特化於View
React不是MV*框架
因此官方自稱為library
可快速開發,但View層外的設計需由開發者構思
日後認為應用不需要到MV*架構的設計
而是如Router、Data Fetching、狀態管理等等功能 元件導向
React應用由元件組成
不需要Model或Controller
元件包含
負責顯示的邏輯或事件處理器
狀態
內容
元件可以持有子元件
是種語法擴充,與React互相獨立
不使用JSX亦可使用React,反之亦然
記述what
例如是開或關的「視覺狀態」
UI以單一狀態定義
UI = f(state)
記述how
例如
更改是開或關的「變化」
依賴於先前的狀態
會導致模態的發生
模態會引起模態錯誤
例如在「將把手向左轉」的模態內,無法移動已經左轉的把手
每次狀態改變都會重新執行元件、建構DOM
Component = (state) => DOM
類似傳統SSR的樣板
實際的DOM處理很慢
React使用JS物件構築虛擬的DOM
Component = (state) => VDOM
更新時會和上次算繪的虛擬DOM做比較
只更新有修改到的部份
並不是「虛擬DOM比較快」,而是「不會變得太慢」
Learn Once, Write Anywhere
use()
React只會在狀態改變時才開始重新算繪
而當一個元件重新算繪時,同時也會重新算繪所有後裔
*React只會重新算繪狀態改變的元件和其後裔,而非整個app
React會找出兩個快照之間的變化,因此會更新元件狀態可能影響的後裔
不論後裔元件有無傳入props,只要元件狀態改變時,就會重新算繪所有後裔
因為React難以確認後裔元件是否與改變的狀態有關
現實的React大多不是純粹的
為了確保app狀態與使用者所看到的UI保持一致,React就會進行重新算繪
React.memo()、React.PureComponent 無視必然的重新算繪請求
告訴React「這個元件是純粹的,只需要在props改變時才重新算繪」
「記憶化」
比起計算有多少後裔,檢查哪個props發生改變更加緩慢、昂貴
因此若預設所有元件是記憶化的,反而會更沒效率
但目前也在探索是否有在編譯階段達成自動記憶化的可能性
而在純粹的元件中,context也會像是「隱形的props」或「內在的props」
例如:
code:javascript
const GreetUser = React.memo(() => {
const user = React.useContext(UserContext);
if (!user) {
return "Hi there!";
}
return Hello ${user.name};
});
GreetUser是純粹的,沒有props
但當user改變時,GreetUser也會進行重新算繪
使用devtools找出重新算繪的元件
<C-S-I>>Profiler>齒輪>Record why each component rendered while profiling
1. 錄影
2. 進行操作
3. 停止錄影
4. 觀看快照記錄中的改變
Highlight updates when components render
更進一步
最佳化
Profiler中的數值不可信,應該使用Performance頁面進行測量
使用低效能的裝置進行測試
Lighthouse分數不是真實使用者體驗的準確反映
co-location
將狀態置於更加相關的地方
composition