/**
* 什么是useRef
useRef返回一个可变的ref对象,该对象的.current属性被初始化为传入的参数。返回的ref对象在组件的整个生命周期内保持不变。
核心特点:
持久化存储:在组件重新渲染时不会被重置
不触发重渲染:修改.current属性不会导致组件重新渲染
同步更新:可以立即获取最新值,不像useState有异步更新的特性
*
* useRef的作用
*1.存储可变值(不触发重渲染)(与useState的区别)
* useState useRef
* 修改值时 触发重新渲染 不触发重新渲染
* 组件重新渲染时 获取之前值 获取之前值
*2.访问 DOM 元素
*3.保存上一次的值
*4.存储定时器 ID
*/
//场景1:访问dom元素
import React, { useRef, useEffect } from 'react';
function FocusInput() {
const inputRef = useRef(null);
useEffect(() => {
// 组件挂载后自动聚焦
inputRef.current.focus();
}, []);
const handleClick = () => {
inputRef.current.focus();
};
return (
<div>
<input ref={inputRef} type="text" placeholder="输入内容" />
<button onClick={handleClick}>聚焦输入框</button>
</div>
);
}
//场景2: 结合useState存储上一次的值
import React, { useState, useRef, useEffect } from 'react';
function Counter() {
const [count, setCount] = useState(0);
const prevCountRef = useRef();
useEffect(() => {
// 在每次渲染后更新 prevCountRef
prevCountRef.current = count;
}, [count]);
const prevCount = prevCountRef.current;
return (
<div>
<h2>当前值: {count}</h2>
<h3>上一次的值: {prevCount}</h3>
<button onClick={() => setCount(count + 1)}>增加</button>
<button onClick={() => setCount(count - 1)}>减少</button>
</div>
);
}
//场景3: 结合useEffect管理定时器
import React, { useState, useRef, useEffect } from 'react';
function Timer() {
const [seconds, setSeconds] = useState(0);
const [isRunning, setIsRunning] = useState(false);
const intervalRef = useRef(null);
useEffect(() => {
if (isRunning) {
intervalRef.current = setInterval(() => {
setSeconds(prev => prev + 1);
}, 1000);
} else {
if (intervalRef.current) {
clearInterval(intervalRef.current);
}
}
// 清理函数
return () => {
if (intervalRef.current) {
clearInterval(intervalRef.current);
}
};
}, [isRunning]);
const handleReset = () => {
setSeconds(0);
setIsRunning(false);
};
return (
<div>
<h2>计时器: {seconds}秒</h2>
<button onClick={() => setIsRunning(!isRunning)}>
{isRunning ? '暂停' : '开始'}
</button>
<button onClick={handleReset}>重置</button>
</div>
);
}
console