R

React useThrottle 钩子及其使用示例

2025-06-09

React useThrottle 钩子及其使用示例

节流是一种技术,其中给定函数在指定的时间段内仅运行一次

在我们的代码针对频繁触发的事件执行昂贵的 CPU / 网络任务的场景中,可以使用节流:

  • 监听 HTML 输入元素的变化
  • 监听窗口大小调整或滚动
  • 监听鼠标光标位置的变化

代码

这是一个用于节流的 React hook

import { useEffect, useRef, useState } from 'react'
function useThrottle<T>(value: T, interval = 500): T {
const [throttledValue, setThrottledValue] = useState<T>(value)
const lastExecuted = useRef<number>(Date.now())
useEffect(() => {
if (Date.now() >= lastExecuted.current + interval) {
lastExecuted.current = Date.now()
setThrottledValue(value)
} else {
const timerId = setTimeout(() => {
lastExecuted.current = Date.now()
setThrottledValue(value)
}, interval)
return () => clearTimeout(timerId)
}
}, [value, interval])
return throttledValue
}
import { useEffect, useRef, useState } from 'react'
function useThrottle<T>(value: T, interval = 500): T {
const [throttledValue, setThrottledValue] = useState<T>(value)
const lastExecuted = useRef<number>(Date.now())
useEffect(() => {
if (Date.now() >= lastExecuted.current + interval) {
lastExecuted.current = Date.now()
setThrottledValue(value)
} else {
const timerId = setTimeout(() => {
lastExecuted.current = Date.now()
setThrottledValue(value)
}, interval)
return () => clearTimeout(timerId)
}
}, [value, interval])
return throttledValue
}
import { useEffect, useRef, useState } from 'react'
function useThrottle<T>(value: T, interval = 500): T {
const [throttledValue, setThrottledValue] = useState<T>(value)
const lastExecuted = useRef<number>(Date.now())
useEffect(() => {
if (Date.now() >= lastExecuted.current + interval) {
lastExecuted.current = Date.now()
setThrottledValue(value)
} else {
const timerId = setTimeout(() => {
lastExecuted.current = Date.now()
setThrottledValue(value)
}, interval)
return () => clearTimeout(timerId)
}
}, [value, interval])
return throttledValue
}

使用示例:监听 HTML 输入元素的变化

import React, { useEffect, useState } from 'react'
import { useThrottle } from './useThrottle'
export default function App() {
const [value, setValue] = useState('hello')
const throttledValue = useThrottle(value)
useEffect(() => console.log(`throttledValue changed: ${throttledValue}`), [
throttledValue,
])
function onChange(event: React.ChangeEvent<HTMLInputElement>) {
setValue(event.target.value)
}
return (
<div>
Input: <input value={value} onChange={onChange} />
<p>Throttled value: {throttledValue}</p>
</div>
)
}
import React, { useEffect, useState } from 'react'
import { useThrottle } from './useThrottle'
export default function App() {
const [value, setValue] = useState('hello')
const throttledValue = useThrottle(value)
useEffect(() => console.log(`throttledValue changed: ${throttledValue}`), [
throttledValue,
])
function onChange(event: React.ChangeEvent<HTMLInputElement>) {
setValue(event.target.value)
}
return (
<div>
Input: <input value={value} onChange={onChange} />
<p>Throttled value: {throttledValue}</p>
</div>
)
}
import React, { useEffect, useState } from 'react'
import { useThrottle } from './useThrottle'
export default function App() {
const [value, setValue] = useState('hello')
const throttledValue = useThrottle(value)
useEffect(() => console.log(`throttledValue changed: ${throttledValue}`), [
throttledValue,
])
function onChange(event: React.ChangeEvent<HTMLInputElement>) {
setValue(event.target.value)
}
return (
<div>
Input: <input value={value} onChange={onChange} />
<p>Throttled value: {throttledValue}</p>
</div>
)
}

CodeSandbox 示例

CodeSandbox 中先前 useThrottle 钩子用法的现场演示。节流值每隔一段时间(默认 500 毫秒)仅更新一次。

链接:CodeSandbox 演示| GitHub 仓库

鏂囩珷鏉ユ簮锛�https://dev.to/loonywizard/react-usethrottle-hook-87h
PREV
如何设计一款 JavaScript 游戏?(13KB 或更小)(2019)
NEXT
带有表情符号的 JS Confetti 库⚡️🎉