SOURCE

/**
 * 什么是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 命令行工具 X clear

                    
>
console