React hooks - 自定义hooks

自定义hooks

        • [自定义封装鼠标位置的 hook](#自定义封装鼠标位置的 hook)
        • [自定义封装秒数倒计时的 hook](#自定义封装秒数倒计时的 hook)

在 src 目录下新建 hooks/index.ts 模块,自定义hooks都写在这里,自定义hooks都以use开头

自定义封装鼠标位置的 hook
javascript 复制代码
export const useMousePosition = (delay:number = 0) => {
  const [position, setPosition] = useState({ x: 0, y: 0 }) // 鼠标的位置
  useEffect(() => {
    let timeId : null | NodeJS.Timeout = null
    const mouseMoveHandler = (e: MouseEvent) => {
      if(timeId !== null) return 
      timeId = setTimeout(() => {
         console.log({ x: e.clientX, y: e.clientY })
         setPosition({ x: e.clientX, y: e.clientY })
         timeId = null 
      }, delay)
    }
    window.addEventListener('mousemove', mouseMoveHandler)
    return () => window.removeEventListener('mousemove', mouseMoveHandler)
  }, [])
  return position // 返回鼠标的位置
}
javascript 复制代码
import { useMousePosition } from '@/hooks/index'
const MouseInfo: React.FC = () => {
  const position = useMousePosition(200) // 调用自定义hooks获取位置,还可以传递参数
  return (
    <>
      <p>鼠标的位置:{JSON.stringify(position)}</p>
    </>
  )
}
自定义封装秒数倒计时的 hook
javascript 复制代码
// 设置hooks函数的类型,num后面加一个?代表可传可不穿,不穿默认为10
type useCountDown = (num?: number) => [number, boolean] 
export const useCountDown: useCountDown = (num: number = 10) => {
  const seconds = Math.round(Math.abs(num)) || 10 // 对边界值进行处理,取绝对值再取整,如果传入为0默认设置为10
  const [count, setCount] = useState(seconds) 
  const [disabled, setDisabled] = useState(true) 
  // useEffect(() => {
  //  let intervalId : null | NodeJS.Interval = null
  //  intervalId = setInterval(() => {
  //     if(count>1) setCount(prev=>prev-1)
  //     else {
  //       clearInterval(intervalId)
  //       setDisabled(false)
  //     }
  //  }, 1000)
  //  return ()=>clearInterval(intervalId)
  // }, [])
  useEffect(() => {
    let timeId : null | NodeJS.Timeout = null
    timeId = setTimeout(() => {
       if(count>1) setCount(prev=>prev-1)
       else {
         clearTimeout(intervalId)
         setDisabled(false)
       }
    }, 1000)
    return ()=>clearTimeout(intervalId)
  }, [count])
  return [restCount,disabled] // 返回鼠标的位置
}
javascript 复制代码
import { useCountDown } from '@/hooks/index'
const MouseInfo: React.FC = () => {
  const [count,disabled] = useCountDown(5) 
  return (
    <>
      <button disabled={disabled}>{disabled?`请仔细阅读本协议(${count})秒`:'请确认协议'}</button>
    </>
  )
}
相关推荐
Eloudy2 小时前
ReAct 原理简介
前端·javascript·人工智能·react.js·agent·gpu
嘟嘟07173 小时前
Next.js 博客左侧笔记列表是怎么从 Redis 渲染出来的?从组件、children 到动态路由一次讲清
redis·react.js·前端工程化
张元清4 小时前
React useInterval Hook:没有过期闭包的 setInterval (2026)
javascript·react.js
MXN_小南学前端4 小时前
React超长文本域中实现“返回顶部”浮动按钮
前端·javascript·react.js
YIAN9 小时前
http无状态?State来展示!从基础路由到鉴权守卫,吃透 SPA 前端路由核心
前端·react.js
console.log('npc')11 小时前
React 19 + Vite 企业级前端项目:从零搭建到规范交付
前端·react.js·前端框架
光影少年11 小时前
react离线缓存、图片缓存方案
开发语言·前端·javascript·react native·react.js·缓存·前端框架
抱抱宝20 小时前
Agent-study项目教程(03):手写 Mini-ReAct Agent(不依赖框架)
javascript·人工智能·gpt·react.js·prompt·agent
想要成为糕糕手1 天前
🚀 在浏览器里跑 DeepSeek-R1?WebGPU 端侧推理实战(六)—— 完结篇:消息渲染与流式收尾
react.js·typescript·llm
YIAN1 天前
从 Hash 底层原理到 React Router v6 实战:我学会了什么?
前端·react.js·vue-router