# React Hook - useRef ###### tags: `Javascript, React` > 1. useRef 跟 useState 很像但是不會觸發 re-render > 1. 通常 reference 在 html 內做的事情是當作連接的橋樑來取得 DOM 元素 > 1. useRef 可以儲存 previous value of state # useRef 基本使用時機 如果你想要計算你的頁面被 render 了幾次你會怎麼寫? 想必很直觀的你會這樣寫: ```javascript= function App() { const [renderCount, setRenderCount] = useState(1); useEffect(() =>{ setRenderCount(prevRenderCount => prevRenderCount +1) }) return ( <div>I render {renderCount } times</div> ); } ``` 接下來你就會看到你的瀏覽器數字開始暴走 * 使用 useEffect 當畫面 re-render 的時候會更新 renderCount * 這時候因為 renderCount 又更新了於是又觸發 useEffect * 無限輪迴開始 ... 所以很顯然的你需要一個不會 re-render 的東西來幫助你,這時候 useRef 就登場了 * useRef 會返回一個物件 {current : 1} 看初始值填入什麼 * 接下來在 useEffect 裡面操作 current * JSX 的地方也要填入 current ```javascript= function App() { const renderCount = useRef(1); // 他會返回一個 {current: 1} useEffect(() =>{ renderCount.current = renderCount.current +1; }) return ( <div>I render {renderCount.current } times</div> ); } ``` 基於 useRef 跟 useState 的使用方式非常像但是,最不一樣的地方是它不會觸發 re-render ,因此這邊是 useRef 最基本的使用情境! # useRef 最常使用的情境 > 通常 reference 在 html 內做的事情是當作連接的橋樑來取得 DOM 元素 這邊要做的範例是 當我們點擊 Focus 時,input 空格會直接進入 Focus 狀態  程式碼的部分 ```javascript= function App() { const [name, setName] = useState(''); const inputRef = useRef() function focus (){ inputRef.current.focus(); } return ( <div className="App"> <input ref={inputRef} value={name} onChange={e => setName(e.target.value)}></input> <div>My name is {name}</div> <button onClick={focus}>Focus</button> </div> ); } ``` 當點擊按鈕時,我們印出 useRef 的內容看看,他其實就會抓 input 的 html 並且並且對其做操作 ```javascript= function focus (){ console.log(inputRef.current); } ``` log 出來的內容就是 input 接下來對他做操作就可以很簡單實現上面程式碼的內容摟!  # 一些使用上的誤區需要注意 因為 useRef 使用上面極其方便,所以我們要避免濫用的情況發生 1. 總是透過 React 管理所有的 state 使用 useState 或是透過 props 2. 避免透過 useRef 來直接使用 value, appendChild 功能(因為它會繞開 useState 直接修改內容) 避免這些情況發生,會讓你的程式碼更容易與人合作 # 另一個常用的情況 儲存 previous value of state ```javascript= function App() { const [name, setName] = useState(''); const prevName = useRef('') useEffect(()=>{ prevName.current = name },[name]) return ( <div className="App"> <input value={name} onChange={e => setName(e.target.value)}></input> <div>My name is {name}, and my name used to be {prevName.current}</div> </div> ); } ``` * 首先使用 useRef 設立一個 prevName 來使用 * 接下來使用 useEffect 來監聽 name value ,並且把 prevName.current 指派給 name 這樣一來 prevName.current 就會是你的 previous state 摟!  這個情況如果使用 useState 來處理的話一定會 re-render 畫面然而那是不需要的所以就是使用 useRef 的好時機 In function component you need to use useRef in order to persist the value between renders
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up