1. 程式人生 > 其它 >Hook鉤子函式--useRef

Hook鉤子函式--useRef

1.介紹

(1)作用:“勾住”某些元件掛載完成或重新渲染完成後才擁有的某些物件(JSX元件轉換後對應的真實DOM物件、在useEffect中建立的變數、子元件內自定義的函式),並返回該物件的引用。該引用在元件整個生命週期中都固定不變,該引用並不會隨著元件重新渲染而失效。

(2)解決社麼問題:useRef可以“獲取某些元件掛載完成或重新渲染完成後才擁有的某些物件”的引用,且保證該引用在元件整個生命週期內固定不變,都能準確找到我們要找的物件。

注意:

①useRef是針對函式元件的,如果是類元件則使用React.createRef()。 ②React.createRef()也可以在函式元件中使用。 只不過React.createRef建立的引用不能保證每次重新渲染後引用固定不變。如果你只是使用React.createRef“勾住”JSX元件轉換後對應的真實DOM物件是沒問題的,但是如果想“勾住”在useEffect中建立的變數,那是做不到的。2者都想可以“勾住”,只能使用useRef。 2.useRef基本用法 (1)針對 JSX元件,通過屬性 ref={xxxRef} 進行關聯。 //先定義一個xxRef引用變數,用於“勾住”某些元件掛載完成或重新渲染完成後才擁有的某些物件 const xxRef = useRef(null); <xxx ref={xxRef} /> (2)針對 useEffect中的變數,通過 xxxRef.current 進行關聯。 useEffect(() => { xxRef.current = xxxxxx; },[]); 3.案例: (1)若我們有一個元件,該元件只有一個輸入框,我們希望當該元件掛載到網頁後,自動獲得輸入焦點。 import React, { useEffect, useRef } from 'react' export default function RefComponent1() { // 先定義一個inputRef引用變數,用於“勾住”掛載網頁後的輸入框 const inputRef = useRef(null); useEffect(() => { //inputRef.current就是掛載到網頁後的那個輸入框,一個真實DOM,因此可以呼叫html中的方法focus() console.log(inputRef.current); // <input type="text"> inputRef.current.focus(); },[]) return <div> {/* 通過 ref 屬性將 inputRef與該輸入框進行“掛鉤” */} {/* 在給元件設定ref屬性時,只需要傳入inputRef,千萬不要傳入inputRef.current */} {/* 在“勾住”渲染後的真實DOM輸入框後,能且只能呼叫原生html中該標籤擁有的方法 */} <input type='text' ref={inputRef} /> </div> } (2)若我們有一個元件,該元件的功能需求如下:元件中有一個變數count,當該元件掛載到網頁後,count每秒自動 +1。、元件中有一個按鈕,點選按鈕可以停止count自動+1。 用useState: import React,{useState,useEffect} from 'react' export defaultfunction Component() { const [count,setCount] = useState(0); const [timer,setTimer] = useState(null); //單獨宣告定義timer,目的是為了讓元件內所有地方都可以訪問到timer useEffect(() => { //需要用setTimer()包裹住 setInterval() setTimer(setInterval(() => { setCount((prevData) => {return prevData +1}); }, 1000)); return () => { //清除掉timer clearInterval(timer); } },[]); const clickHandler = () => { //清除掉timer clearInterval(timer); }; return ( <div> {count} <button onClick={clickHandler} >stop</button> </div> ) } 用useRef: export default function RefComponent() { const [count, setCount] = useState(0); const timerRef = useRef(null); useEffect(() => { // 將timerRef.current與setInterval建立的計時器進行“掛鉤 timerRef.current = setInterval(() => { setCount(prevData => prevData + 1) }, 1000); return () => { // 通過timerRef.current,清除掉計時器 clearIInterval(timerRef.current) } }, []) const clickHandler = () => { clearInterval(timerRef.current) } return ( <div> {count} <button onClick={clickHandler} >stop</button> </div> ) } 注意 ①如果需要對渲染後的DOM節點進行操作,必須使用useRef。 ②如果需要對渲染後才會存在的變數物件進行某些操作,建議使用useRef。
強調:useRef只適合“勾住”小寫開頭的類似原生標籤的元件。如果是自定義的react元件(自定義的元件必須大寫字母開頭),那麼是無法使用useRef的。