**`useRef`**是一个非常实用的钩子函数
一、访问和操作 DOM 元素
1. 获取 DOM 元素引用
1.1 基本原理
通过 `useRef` 我们可以直接操作 DOM 元素
1.2 代码示例
javascript
import React, { useRef, useEffect } from "react";
const InputFocusComponent = () => {
const inputRef = useRef(null);
useEffect(() => {
// 组件挂载后,使输入框获得焦点
if (inputRef.current) {
inputRef.current.focus();
}
}, []);
return (
<div>
<input type="text" ref={inputRef} />
</div>
);
};
export default InputFocusComponent;
2. 跨渲染周期保持引用
2.1 渲染周期中的稳定性
例如:在一个定时器的场景中,需要在组件挂载时启动定时器,并在组件卸载时清除定时器,`useRef`可以帮助我们保持对定时器 ID 的引用。
2.2 代码示例
javascript
import React, { useRef, useEffect, useState } from "react";
const TimerComponent = () => {
const timerRef = useRef(null);
const [count, setCount] = useState(0);
useEffect(() => {
// 组件挂载时启动定时器
timerRef.current = setInterval(() => {
setCount((prevCount) => prevCount + 1);
}, 1000);
return () => {
// 组件卸载时清除定时器
if (timerRef.current) {
clearInterval(timerRef.current);
}
};
}, []);
return (
<div>
<p>Seconds passed: {count}</p>
</div>
);
};
export default TimerComponent;
二、保存可变值
1. 避免重新渲染触发的问题
1.2 与 state 的区别
例如:在一个数据获取的场景中,获取数据时不需要触发组件渲染。
1.3 代码示例
javascript
import React, { useRef, useState, useEffect } from "react";
const DataFetchingComponent = () => {
const isFetchingRef = useRef(false);
const [data, setData] = useState(null);
useEffect(() => {
if (!isFetchingRef.current) {
isFetchingRef.current = true;
fetch("https://example.com/api/data")
.then((response) => response.json())
.then((jsonData) => {
setData(jsonData);
isFetchingRef.current = false;
});
}
}, []);
return (
<div>
{data ? (
<pre>{JSON.stringify(data)}</pre>
) : (
<p>
{isFetchingRef.current ? "Fetching data..." : "No data available"}
</p>
)}
</div>
);
};
export default DataFetchingComponent;