React useThrottle 钩子及其使用示例
节流是一种技术,其中给定函数在指定的时间段内仅运行一次
在我们的代码针对频繁触发的事件执行昂贵的 CPU / 网络任务的场景中,可以使用节流:
- 监听 HTML 输入元素的变化
- 监听窗口大小调整或滚动
- 监听鼠标光标位置的变化
代码
这是一个用于节流的 React hook
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
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 | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
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 输入元素的变化
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
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> | |
) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> | |
) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
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 毫秒)仅更新一次。
鏂囩珷鏉ユ簮锛�https://dev.to/loonywizard/react-usethrottle-hook-87h