hook

使用hook注意事項

circle-exclamation

useState

基本用法

  • class(setState) vs function(useState)

React 提供的 Hook-useState。我們有時也稱它做「State Hook」。前所未有地,它讓我們能夠增加 local state 到 React function component!

+// 引入
+ import React, { useState } from 'react';

functidon Example() {
+ // 宣告一個新的 state 變數,我們稱作為「count」。
+ const [count, setCount] = useState(0);
  return (
    <div>
+// 顯示state 變數
+     <p>You clicked {count} times</p>
+// 更變state 變數 觸發重新渲染
+      <button onClick={() => setCount(count + 1)}>
      </button>
    </div>
  );
}

log的地方

你可以把log放在組件的地方,而不是函式中,來觀察渲染的變化,單看畫面是看不出來!!

prevState用法

  • 多次呼叫setState方法時,可能會因為前一個狀態未被更新而出現狀態不一的狀況,這時可以於setState內放入函式更新來獲取prevState,用法如下

我覺得這很像data race的情況,setState是非同步的呼叫,因此需要注意資料可能會有不同步的狀況,所以利用prevState去解決它.

參考網路範例說明:

useEffect

可以把 useEffect 視為 componentDidMountcomponentDidUpdatecomponentWillUnmount 的組合。

使用說明

  • 需注意useEffect內動作與dependencies參數的互動,否則會進入無窮迴圈.

  • useEffect 有什麼作用? 透過使用這個 Hook,你告訴 React 你的 component 需要在 render 後做一些事情。React 將記住你傳遞的 function(我們將其稱為「effect」),並在執行 DOM 更新之後呼叫它。

放置的地方

官方-hooks-effectarrow-up-right 重點:

  • 內有使用class與hook 的範例對比說明

函式該寫進useEffect裡面或外面

  • 如果某個函式不需要被覆用,那麼可以直接定義在 useEffect 中

  • 需要被覆用,把該方法提到 useEffect 外面後,記得用 useCallback 進行處理後再放到 useEffect 的 dependencies 中,來讓useEffect知道到底有沒有資料狀態的變化(處理不好會陷入無窮迴圈)。

陷入無窮迴圈

你可以藉由一個一個移除依屬 (dependencies) 來發現到底是哪個值。然而,移除一個依屬(或盲目地使用 [])通常是錯誤的修正方式。

應該要修正這個問題的根源。例如,放入函式可能造成這個問題,將它們放到 effects 裡,或抽出他們到上層,或是將他們包在 useCallback 裡都可能會有幫助。為了避免重複產生新的物件,useMemo 也可以達成類似的目的。

useCallback

  • 用法與useEffect參數傳遞很像,但會回傳一個memoized 的Callback

  • 可以記憶住該 function 的記憶體位置,避免每一次子元件 re-render 時都因為 function 的記憶體位置改變導致子元件重新渲染。

  • useCallback(fn, deps) 相等於 useMemo(() => fn, deps)

  • 常用在

useMemo

  • 傳遞一個「建立」function 及依賴 array。useMemo 只會在依賴改變時才重新計算 memoized 的值。這個最佳化可以避免在每次 render 都進行昂貴的計算

  • 不要濫用,需用在複雜的計算,例如可能要 map 一組很大的陣列,這時候可能就值得運算結果暫記起來下次用。

  • My Note: 透過log可以得知有沒有重複計算或是profile可以得知計算速度的減少狀況

useRef

[Day 27 - 即時天氣] React 中的表單處理(Controlled vs Uncontrolled)以及 useRef 的使用arrow-up-right

在 React 中表單元素的處理主要可以分成兩種 Controlled 和 Uncontrolled 這兩種 像是 這類的表單元素本身就可以保有自己的資料狀態,可以直接透過 JavaScript 再取出該元素的值document.querySelector,因為使用者輸入的內容可以直接保存在 元素內。

針對表單元素, React 會建議我們使用 Controlled Components,基本上使用 Controlled Components 和 Uncontrolled Components 都能達到一樣或類似的效果

  • Uncontrolled Components - useRef 的使用

但要特別留意的是:「當 input 欄位內的資料有變動時,並不像 Controlled Component 一樣會促發畫面重新渲染」,因此,若有重新渲染畫面的需求,建議還是使用 Controlled Component 來處理

範例 useRef指到某個html中:

  • 當我們把 useRef 回傳的物件透過 rel 的方式放到 HTML 元素中時,就很像是用 document.querySelector 去選到該元素後,保存在 useRef 回傳物件的 current 屬性內。

----

circle-info

useRef 除了可以搭配 ref 指稱到某一 HTML 元素來使用之外,當我們在 React 組件中想要定義一些「變數」,但當這些變數改變時,又不需要像 state 一樣會重新導致畫面渲染的話,就很適合使用 useRef。

範例:useRef 定義變數

有些時候想要看某個組件被重新渲染了幾次,就可以類似這樣寫

重複的問題

無限迴圈

之前用了一個usecallback 去呼叫api,結果造成無限次呼叫,原本以為會不會跟api回傳值有關,但其實是因為只有當 dependencies 有改變時,useCallback 才會回傳一個新的函式,而我參數放了一些陣列進去,網路上有一些关于react的useEffect的依赖比较问题,在hook的底层源码是用Object.is来进行浅比较的 use-deep-compare-effect深比较解读,或建議使用JSON.stringify等等。see useeffect-comparing-objects:

重複渲染

state改變就會引起重新渲染,在創建參數時要注意是否有必要使用usestate去設置參數。

reference

Last updated