相信有過 React
使用經驗的人對 ref
都會熟悉,它可以用來獲取元件例項物件或者是DOM物件。
而 useRef
這個 hooks
函式,除了傳統的用法之外,它還可以“跨渲染週期”儲存資料。
首先來看一下它傳統的用法:
import React, { useState, useEffect, useMemo, useRef } from 'react';
export default function App(props){
const [count, setCount] = useState(0);
const doubleCount = useMemo(() => {
return 2 * count;
}, [count]);
const couterRef = useRef();
useEffect(() => {
document.title = `The value is ${count}`;
console.log(couterRef.current);
}, [count]);
return (
<>
<button ref={couterRef} onClick={() => {setCount(count + 1)}}>Count: {count}, double: {doubleCount}</button>
</>
);
}
程式碼中用 useRef
建立了 couterRef
物件,並將其賦給了 button
的 ref
屬性。這樣,通過訪問 couterRef.current
就可以訪問到 button
對應的 DOM
物件。
然後再來看看它儲存資料的用法。
在一個元件中有什麼東西可以跨渲染週期,也就是在元件被多次渲染之後依舊不變的屬性?第一個想到的應該是 state
。沒錯,一個元件的 state
可以在多次渲染之後依舊不變。但是,state
的問題在於一旦修改了它就會造成元件的重新渲染。
那麼這個時候就可以使用useRef來跨越渲染週期儲存資料,而且對它修改也不會引起元件渲染。
import React, { useState, useEffect, useMemo, useRef } from 'react';
export default function App(props){
const [count, setCount] = useState(0);
const doubleCount = useMemo(() => {
return 2 * count;
}, [count]);
const timerID = useRef();
useEffect(() => {
timerID.current = setInterval(()=>{
setCount(count => count + 1);
}, 1000);
}, []);
useEffect(()=>{
if(count > 10){
clearInterval(timerID.current);
}
});
return (
<>
<button ref={couterRef} onClick={() => {setCount(count + 1)}}>Count: {count}, double: {doubleCount}</button>
</>
);
}
在上面的例子中,我用 ref
物件的 current
屬性來儲存定時器的ID,這樣便可以在多次渲染之後依舊儲存定時器ID,從而能正常清除定時器。
更多前端知識,請關注小程式,不定期有驚喜!