在React世界中,useState是一個很基礎的Hook,就跟Vue世界的ref和reactive一樣,所以其實使用概念上真的還算簡單。不過就在我以為我早就懂它的時候,卻還是默默踩到了一些蠢蠢的雷,這才發現原來我根本沒有搞懂它啊!所以我就來記錄一下useState這個看似平凡,但又隱藏一些需要注意的點的Hook了!
useState的基本用法
- 呼叫useState hook時,可以帶入當作state初始值的參數。
- 呼叫useState hook時,會回傳一個array,array中的第一個元素是state,第二個元素是用來變更這個state的function,可以用解構賦值的方式取用(如第一張圖)。
- 要變更state時,可以取用useState回傳物件中index為1的元素,以上面的例子來說,就是setState,將要變成的值當作參數使用setState就可以變更state,例如:setState(3),state就會從原本的0變成3。
到這邊為止都是很基本到不行的用法,但實際上使用時,卻還有一些需要特別注意的地方。
useState使用注意事項
雖然useState的基本用法非常簡單易懂,但其實知道了這些使用注意事項,才能說自己真的懂useState怎麼使用,也才能真正避開useState隱藏的雷。
- 直接使用state來setState可能會無法正常更新state
setState這個更新state的function是非同步進行的function,所以如果直接以下面這樣的寫法來更新state的話,有可能會拿到前一次還未變更的state來進行state的更新。
解決方法
要使用當次更改前的state來更新state時,要帶入previousState來操作,實際寫法如下。
雖然以這個加一的例子來說,帶入state+1,好像沒有什麼問題,但如果是比較複雜的操作,可能就會發生一些問題,導致setState更新後的state有異常。
- 初始值是物件時,直接把要變更的值當參數帶入setState會蓋掉整個物件
如果初始值是物件的話,當只想要改其中一個key的值,如果直接把要改的那個值帶入,會蓋掉原本的整個物件。
例如以下這個寫法,就是會讓整個物件都被改掉。
實際呈現的狀況會是這樣
解決方法
要避免這樣的情況發生,就要用先把previousState解開,再把要更新的內容更新上。(也就是利用展開運算子"...",先將原本的物件展開,再將要修改的屬性覆蓋上去)
寫法就會是以下這樣,這樣就不會蓋掉原本的object內的其他屬性了。
Name不會再被蓋掉了!
- setState後,無法直接拿到變更後的state進行操作
這個部分也是我自己最近撞到的雷,因為很自然地就會想要在setState後,直接拿更新的state來進行下一步動作,但是卻忘記setState是非同步進行的funtcion,所以這樣的動作,會導致拿到還沒更新好的state去進行下一步。
直接看範例程式碼吧!
每次點擊+1時,印出來的數字都是+1前的數字。
解決方法
如果需要在setState後,拿到更新的state進行下一步動作的話,可以使用useEffect來監聽state,這樣可以確保state有被更新後,再進行下一步。
(useEffect用法的部分,之前也有寫一篇學習筆記,可以搭配參考。)
以上就是這次自己在使用useState的時候,覺得很重要,要小心的部分。
就這樣囉!打完收工!
留言列表