useRef
Hook 保存的值,不會因為每次元件 Render 而重新被創造。在初始化後,使用 useRef
回傳出來的物件,會始終指向同一個 Reference。
// 宣告
const refObject = useRef('initialValue');
// 取得 => 使用 .current 屬性取得值
console.log(refObject.current) // 'initialValue'
// 變更不會觸發 render
refObject.current = 'newValue'
執行結果:https://codepen.io/lala-lee-jobs/pen/abGZNNO?editors=0011
執行結果:https://codepen.io/lala-lee-jobs/pen/YzLpZPJ?editors=0011
因為 useRef 不會因為更新元件而被改變 Reference 的特性,讓它常常被應用在以下的情境
有一個輸入框,按下按鈕後,Focus 到該輸入框。
function App() {
// 宣告
const inputRef = useRef(null);
// 在程式中操作 input DOM 的 Ref
const focusInput = () => {
inputRef.current.focus();
};
return (
<>
<!-- 指定 inputRef 為 此 input DOM 的參考 -->
<input type="text" ref={inputRef} />
<button onClick={focusInput}>Focus Input</button>
</>
);
}
執行結果:https://codepen.io/lala-lee-jobs/pen/ZEoBeXJ?editors=0011
function App() {
const timer = useRef(null);
const [count, setCount] = useState(0);
useEffect(() => {
timer.current = setInterval(() => {
setCount(count => count + 1);
}, 1000);
return () => clearInterval(timer.current);
},[]);
return (
<>
<span>開始計時</span>
<span>{count}</span>
</>
);
}
執行結果:https://codepen.io/lala-lee-jobs/pen/KKRNmRB?editors=0011
function App() {
const [inputValue, setInputValue] = React.useState('');
const previousInputValue = React.useRef('');
React.useEffect(() => {
previousInputValue.current = inputValue;
}, [inputValue]);
return (
<>
<input
type="text"
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
/>
<h2>Current Value: {inputValue}</h2>
<h2>Previous Value: {previousInputValue.current}</h2>
</>
);
}
執行結果:https://codepen.io/lala-lee-jobs/pen/zYjowLV?editors=0011
通常會在原生 HTML DOM 元素上使用 useRef,用以取得該 DOM 節點的參考。但是自製的元件就無法對其使用 useRef,要如何取得自製元件的參考,就是接下來要介紹的 forwardRef
的功能。
https://www.w3schools.com/react/react_useref.asp
https://juejin.cn/post/6854573209639976974