接續昨天...
既然不能用 Redux 來存畫布,那畫布的部分我改成用 useContext 來存吧!
當下看起來,要在多個 component 裡使用、且不使用 Redux,好像也只能這麼做才能在多個 component 傳遞變數。
當然,使用 useContext 有個明顯的問題,那就是:
所有在這個 context 裡的東西,只要 context 傳送的變數有改變,每個 component 都會重新 render
如果
context
中的值發生變化,所有消費該context
的組件都會重新渲染。這是因為 React 需要確保所有依賴於context
值的組件都能夠反映最新的狀態。
雖然畫布已用 context 傳送,但圖像操作的 function 散落在各個不同的 component裡,遇到不同 function 有交互關係的行為時,跨 component 不太容易寫邏輯。
所以後來將所有圖像操作的 function 全部集中,放到一支 custom hook 裡使用。
context
的 component 也跟著頻繁render前面有說到,使用的套件把 canvas本體、selectedObjects...等變數都視為是 state
畫布一有改變(任何形式的變化),會觸發 context
傳送新變數到各 component => 然後所有有使用此畫布的 component 都重新 render。
乍聽之下還好,但這件事在繪圖功能一多的時候,效能消耗就會變得倍數可怕。
假如我有十個不同繪圖功能的按鈕在畫面上(分屬於不同 componet 面板),
我分別在按鈕中引入 custom hook 中相應對的繪圖 function
每次畫布有改變的話,單個 component 會有的 render 順序:
context
改變 -> custom hook -> 單個 component
然後以上x10個 component
這就是每次畫布改變(就算裡只是選取物件)所有會 render 的物件 3*10 = 30
次的(不必要) render
😱
這樣一定是不行的吧,至少加上 memo 或是 useCallback
最後是使用 React.memo
(用在所有有使用畫布參數的component上) +useCallback
(用在custom hook 裡的繪圖 function) ,來避免未使用到此 function 時,個別 component 的重新渲染。
整體而言,目前就算加上 useCallback 或是 memo,每改變畫布一次還是會處發一些相關物件render,並不是最理想狀態。
直到發現其實改變 canvas 並不需要拿到 canvas 本體的最新變數,只要對他的記憶體空間處理就好...
是時候把套件拔掉了
明日待續
稍作整理一下,目前為止的架構:
-> 存在 context 裡,供全部 component 使用
-> 全部放在一支 custom hook 裡,並在此 hook 中引入 context 的畫布
-> 引入 custom hook 裡的 個別繪圖 function 使用