Hook踩坑記:React Hook react-unity-webgl
- 2020 年 6 月 9 日
- 筆記
- React, react-unity-webgl, unity3d
自公司前後分離上手React以來,一個坑一個坑的踩,Class的全生命周期雲里霧裡,還么屢明白,就抱上了Hook的大腿不鬆手,確實爽到飛起。修改到Hook的過程基本比較順暢,直接少了三分之一的程式碼,組件更容易封裝,調試更方便,諸多優點在此不再贅述,已有各路大佬紛紛評價,此處貼上中文官方地址:React-Hook文檔。這裡主要講講修改到一塊關於 Unity 3D模型載入的踩坑記。
背景:React 載入 Unity 3D模型 ,使用到一個插件 react-unity-webgl,感興趣的盆友可以自行查閱。
因為Class改Hook處理語法變動,邏輯程式碼基本不用怎麼改動,所以基本沒有阻力,但是當我把這塊業務程式碼改成Hook時,跟模型交互時通訊失敗,無法驅動模型動作。百思不得其解,弄了倆測試頁面,test_hook、test_class,只能debugger,一步一步調,發現一些端倪。
Class 有些初始化的程式碼 都寫在了constructor(props){},這個大家都明白,第一次載入頁面的時候會走。hook呢,最外層是一個大方法,之前遷移的時候就寫在方法里最頂部了,也沒什麼問題。載入模型第一句是 const unityContent = new UnityContent(參數1,參數2);兩個頁面都能載入出來模型,但是跟斷點發現hook頁面的 unityContent 對象比class的缺少了一個重要的屬性:unityInstance,通訊的方法就是靠它 Send() 的,而且發現同一個對象,屬性id一直在變,原來每次修改state時,都會走聲明的這段方法,導致每次都 new 一個新的對象,導致unityInstance屬性沒有正確掛在unityContent對象上。
在知道大概原理的情況下,搞成全局變數,在載入時判斷是否已經初始化,問題就迎刃而解了(其實費了九牛二虎之力)。
寫過hook的盆友第一反應會想到聲明寫到useEffect,然後 [] 只執行一次才是正確的寫法。
之所以沒有呢,是因為模型載入跟其他的業務沒什麼關係,我並不需要渲染完整個DOM在來載入,並且載入模型很費時間,必須要剛載入頁面就同時載入模型,所以才有此次踩坑記。
總結:Hook寫在useEffect之外的程式碼會多次載入(包括刷新狀態),要做好判斷,否則很容易產生bug。更推薦(官方推薦)按業務按順序把初始化方法寫到useEffect。