You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Q1. 在 React 中去保持 state 資料的 immutable的重要為何?
React 資料為單向資料流, 透過產生一個新的值來取代舊的. 而非去修改此值, 否則有可能導致資料流的可靠性被破壞, 或某些機制無法正常運作.
Q2. 為什麼不要做deep clone的原因?
如果是巢狀結構的話, deep clone會進行深層遍歷, 將既有資料的值作複製. (且當有不必要的複製) 有機會產生效能上的問題及記憶體的浪費 React 機制優化也會受影響, 因為重新取值(為不同物件). 失去參考相等性.
補充說明
Q3. 深或淺拷貝的區別是什麼?
Q4. 在immutable update時須注意什麼?
僅針對實際要更新的那層即可, 因可能只有修改特定資料, 如做deep clone會浪費效能.
Q5. 範例 .(範例參考: p.214)
針對巢狀式參考型別資料範例,
https://codesandbox.io/p/sandbox/qr-code-3-3-3-forked-mts6kf?file=%2Fsrc%2FApp.jsx
為了更改x值, 進行兩次拷貝. 故之後在更改x值時, 才不會改到原本的資料
=> 示範在巢狀式參考型別資料中, 正確的做 immutable update
Q6. 針對書上提到的陣列方法中有哪些 immutable update 方法?
有些js 原生的物件方法. 能直接回傳一個的新的物件, 比如說slice or filter 可避免mutate到原有物件
Q7. 分享章節重點想法.
3-3
3-4
巢狀式參考型別資料時, 須注意其 immutable update方式.
在更新巢狀式參考型別資料時, 不僅外層需要複製並產生新的參考, 裡面的每一層有屬性項目欲更新的物件或陣列也需要複製並"產生全新的參考"(沒有要更新的屬性或項目則不用動, 沿用舊參考), 然後覆蓋上想更新的內容, 方能保證既有資料的immutable update
Q8. 在深拷貝上遇到的雷, 導致抓資料上 及 hook 的話 會遇到什麼問題,
實務上經驗分享
聊天室系統的某小元件每三秒更新一次, 以確保資料為最新值.
但可能實際上3秒後可能仍是舊資料, 但來的資料是全新物件(不同記憶體位置), 導致頁面不斷重複不必要的渲染. 雖非手動深拷貝, 卻有次狀況產生...
解決方法分享
聊天室新的發言出現時. 更新一個值(代表版本或印記)
每當更新資料時, 讓代表版本的值做更新, 未來再拉資料, 只需比對新舊版是否一樣來進行處理(排除對比整包資料)
Q9. 為什麼不建議用deep clone的? // Zet補充分享
須先了解
React 畫面優化方式:
資料比較機制:
其由來是為了排除產生不必要的reactElement 達到效能優化.
(非React機制必要性的一部份, 也與畫面正確性沒關係, 只是for效能優化)
對React來說在每次資料間的比較時, React不需要知道資料的細節是否一模一樣.
當面對不同型別時..
故為何不需要使用深拷貝?
因深拷貝後複製出來的新資料為完全獨立, 即使沒發生更新的內層資料也會產生全新的參考
當參考改變了, 對有些效能優化機制來說也失去參考相等性.
連結: https://codesandbox.io/s/immutable-update-shallow-deep-clone-kt253j
< Case 1 >
// 巢狀結構 case
foo沒有被更新原因為, memo包住的child . 因是巢狀結構, 而解構方式僅會淺拷貝外層, 內部仍指向同個記憶體, 故也被認定新舊的data.foo皆指向同個記憶體的obj, 沒被改動到, 故不會觸發re-render.
< Case 2 >
< Case 3 >
// 此case 正常是因為b為原型資料為immutable, 可直接值與值比較來判斷資料是否相同,
即使做了deep clone, 但因可值與值間做比較. 故顯示正常. 但仍不該使用deep clone!!
綜合上述, immutable重點在於「沿用 沒有內容更新需求 的參考, 新增 有內容更新需求 的參考 」
Q10. 如只希望子 component 接受到的 props 有改變的時候才 re-render 的話, 就都應該要將這個子 component 都用memo 包裝嗎?
遇到效能問題時才需要.
Q11. 3-4 提到的參考型別和物件型別指的是相同的東西嗎?
參考型別 === 物件型別. 其正式說法為"物件型別"!!
Note!! 此處的"物件型別"並不是指物件. 因在JS中, 原始型別以外都稱物件型別(如陣列或function), 但擔心讀者誤以為只有物件且不含陣列, 故此章節寫為參考型別替之.
Note.
Beta Was this translation helpful? Give feedback.
All reactions