Pressidian
花园入口
笔记
项目
关于
实验室
GitHub
花园入口
笔记
项目
关于
实验室
GitHub

KNOWLEDGE PATHS

笔记库
当前位置
笔记库/前端/项目笔记/代达罗斯/模式

useDebounce

1 分钟阅读 · Note

目录树 578 篇

            • 表单最佳实践指南
            • 双层级导航结构
            • 以schema为中心的
            • 异步三态切换
            • 用neverthrow进行错误处理
            • Anatomy
            • cn
            • LoadingState&useList的组合
            • procedure中的service位置
            • scrollbar-gutter
            • TailwindCSS
            • TanStack Router 路由模式
            • useDebounce
            • useForm
            • void
          • 项目待做
          • 性能优化
          • UI设计
      • 前端技术栈
    • 笔记目录
    • CLAUDE.md
    • Vue 组件与 Render 函数

关联笔记 6

↗表单最佳实践指南同一路径↗双层级导航结构同一路径↗以schema为中心的同一路径↗异步三态切换同一路径↗用neverthrow进行错误处理同一路径↗Anatomy同一路径
  • useDebounce

useDebounce

> Last Format Time:7/14/2026 20:56:57

这里和普通的防抖函数不同,这里是要将防抖通过react hooks来实现的:

这里的是在项目中AI写的,具体的来看这里的ref是不必要的,因为使用const来声明的变量在这里是可以的:

import { useState, useEffect, useRef } from "react";

export function useDebounce<T>(value: T, delay: number): T {
  const [debounced, setDebounced] = useState(value);
  const timerRef = useRef<ReturnType<typeof setTimeout>>(undefined);

  useEffect(() => {
    timerRef.current = setTimeout(() => setDebounced(value), delay);

    return () => clearTimeout(timerRef.current);
  }, [value, delay]);

  return debounced;
}

为什么 useRef 不需要? useEffect 的 cleanup 函数通过闭包已经捕获了当次 effect 创建的 timer,每次 value/delay 变化时旧 effect 的 cleanup 会精确清除那个 timer,新 effect 创建新 timer。整个过程不需要跨渲染持久化 timer 的引用:

import { useState, useEffect } from "react";

export const useDebounce = function<T>(value: T, delay: number = 500): T {
  const [debounced, setDebounced] = useState(value);

  useEffect(() => {
    const timer = setTimeout(() => setDebounced(value), delay);

    return () => clearTimeout(timer);
  }, [value, delay]);

  return debounced;
};

个人默写:

import { useEffect, useState } from "react"

export const useDebounce<T> = (value: T, time: number = 300): T => {
	const [ debounced, setDebounced ] = useState(value)
	useEffect(() => {
		const timer = setTimeout(() => setDebounce(value), time)
		return () => clearTimeount(timer) 
	}, [ value, time ])

	return debounced
}