前言: 這篇文章會假設你已經對 react hook 有一些基礎的了解. 主要討論什么是 useRef , useRef 與 createRef 的區別, 以及在什么情況下使用 useRef .
什么是 useRef
首先, 我們要實現一個需求 -- 點擊 button 的時候 input 設置焦點.
createRef API
同樣的, 我們可以使用 useRef 來實現完全相同的結果.
useRef Hook
從上面的例子看, createRef 和 useRef 的作用完全一樣, 那為什么 react 要設計一個新的 hook ? 難道只是會了加上 use , 統一 hook 規范么?
createRef 與 useRef 的區別
事實上, 只要你認真讀一下官方文檔, 就會發現, 它們兩個確實不一樣.
官網的定義如下:
useRef
returns a mutable ref object whose .current
property is initialized to the passed argument (initialValue
). The returned object will persist for the full lifetime of the component.
換句人話說 , useRef 在 react hook 中的作用, 正如官網說的, 它像一個變量, 類似於 this , 它就像一個盒子, 你可以存放任何東西. createRef 每次渲染都會返回一個新的引用,而 useRef 每次都會返回相同的引用。
如果你還不太理解, 沒關系. 我們再用一個例子來加深理解 createRef 和 useRef 的不同之處.
仔細看上面的代碼. 它會輸出什么 ?
就算組件重新渲染, 由於 refFromUseRef 的值一直存在(類似於 this ) , 無法重新賦值. 運行結果如下:

何時使用 useRef
為什么要設計 useRef 這個 API ? 我們來結合實際的應用場景來看看. 看一個經典的例子.
你猜 alert 會彈出什么?
是界面上 count 的實時狀態 ? 還是在點擊 button 時 count 的快照 ?

最終結果是 在count為6的時候, 點擊 show alert , 再繼續增加 count , 彈出的值為 6, 而非 10.
為什么不是界面上 count 的實時狀態?
實際的實現原理復雜得多, 此處可以先簡單的理解成下面的普通函數執行.
當我們更新狀態的時候,React 會重新渲染組件, 每一次渲染都會拿到獨立的 count 狀態, 並重新渲染一個 handleAlertClick 函數. 每一個 handleAlertClick 里面都有它自己的 count .
既然這樣, 我們就理解了上面的例子, alert 出來的值, 就是當時點擊時的 count 值.
如何讓點擊的時候彈出實時的 count ?
因為 useRef 每次都會返回同一個引用, 所以在 useEffect 中修改的時候 ,在 alert 中也會同時被修改. 這樣子, 點擊的時候就可以彈出實時的 count 了.
上面的問題解決了, 我們繼續, 我們希望在界面上顯示出上一個 count 的值. 上代碼. 上面的問題解決了, 我們繼續, 我們希望在界面上顯示出上一個 count 的值. 上代碼.
獲取上一個值, 這在實際場景中並不少, 我們嘗試把它封裝成自定義 hook .
好了, 這樣子我們就可以在函數式組件中方便的獲取上一次的值. 這樣, 我們就可以簡單的實現類組件中 componentDidUpdate 獲取 prevProps 的值了.
總結
useRef 不僅僅是用來管理 DOM ref 的,它還相當於 this , 可以存放任何變量.
useRef可以很好的解決閉包帶來的不方便性.你可以在各種庫中看到它的身影, 比如 react-use 中的 useInterval , usePrevious ……
值得注意的是,當 useRef 的內容發生變化時,它不會通知您。更改.current屬性不會導致重新呈現。因為他一直是一個引用 .
轉自https://zhuanlan.zhihu.com/p/105276393
喜歡這篇文章?歡迎打賞~~