# About Ref in React ### 1. 開頭 refs和state十分相似,兩者都能建立變數,並且對其進行讀跟寫 ``` const [num, setNum] = useState(0) const number = useRef(0) ``` useState必須使用特定的設定涵式來進行state的設定,而useRef(initialValue)則是會return一個 **{ current: initialValue }的物件** ,可以使用.current的方式直接進行讀跟寫。 例: ``` number.current = 1 console.log(number.current) // 1 ``` ### 2. 相異處 #### 而兩者最大的不同點在於state改變的時候會觸發re-render,反之refs並不會觸發re-render 因此就會發生以下的情況: ``` 1. 在按下button後,button上的數字會隨著按的次數增加 const [count, setCount] = useState(0); function handleClick() { setCount(count + 1); } return ( <button onClick={handleClick}> You clicked {count} times </button> ); ``` ``` 2. 在按下button後,由於不會re-render因此button上的數字不會隨著按的次數增加 let countRef = useRef(0); function handleClick() { // This doesn't re-render the component! countRef.current = countRef.current + 1; } return ( <button onClick={handleClick}> You clicked {countRef.current} times </button> ); ``` 並且若state改變了值,新的值必須在進行re-render過後才能夠被取得(**re-render的觸發時機是在function完整執行完後才會觸發**)。 而refs則是會**立刻改變**而且能立刻讀到更新過後的值。 然而雖然兩者看起來有點相似,但在基本上都會以使用useState為主,因為refs是一種 “escape hatch” 在通常情況下並不會頻繁的做使用。 ### 3. 對比 | refs | state | |:-----------------------------------------:|:--------------------------------------------:| | useRef(value) 會 return { currnet: value } |useState(value)會return一個[state, setState] | | 當值被更新時**不會**觸發re-render | 當值被更新時**會**觸發re-render | |current的值本身能夠進行更改跟讀取|值不能進行更改,必須使用提供的設定涵式才能對值進行更改,並且新的值要在re-render後才能得到| |不要在render時對refs進行讀或寫,容易讓程式變得難以預測|可在任何時候進行讀跟寫| ### 4. refs使用時機 通常refs會使用在不需要render的東西,或者是DOM的element上 1. 像是如果我們想知道畫面re-render的次數,如果這時假如使用state進行計數的話 ``` const [renderTimes, setRenderTimes] = useState(0) useEffect(()=>{ setRenderTimes(prev=>prev+1) }) // 由於state改變造成re-render,而re-render又觸發useEffect,因此形成無限迴圈 ``` 但如果改成用refs實作的話就能進行計算 ``` import React, { useState, useEffect, useRef } from 'react'; export default function Counter() { const [text, setText] = useState('') const renderTimes = useRef(1) useEffect(()=>{ renderTimes.current = renderTimes.current + 1 console.log('render') }) return ( <> <input value={text} onChange={data=>setText(data.target.value)}/> <div>text = {text}</div> <div>renderTimes = {renderTimes.current}</div> </> ) } ``` 2. 使用在DOM的element上的話 ``` 實現按button後focus到input上 const inputRef = useRef(null); function handleClick() { inputRef.current.focus(); } return ( <> <input ref={inputRef} /> <button onClick={handleClick}> Focus the input </button> </> ); ``` --- 參考資料: https://react.dev/learn/referencing-values-with-refs https://react.dev/learn/manipulating-the-dom-with-refs https://www.youtube.com/watch?v=42BkpGe8oxg https://www.youtube.com/watch?v=t2ypzz6gJm0
×
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