接續昨天...
既然不能用 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 使用