JavaScript中的防抖与节流、在react class及hook中使用防抖与节流


函数防抖:函数被触发后过一段时间再执行,如果在这段时间内又被触发,则重新计时,即将多次高频操作优化为只在最后一次执行。应用场景为用户连续输入,只需要在输入结束后做一次校验即可,比如input搜索或校验。简而言之,就是在input请求时使用防抖。

function debounce(func, ms = 1000) { let timer; return function (...args) { if (timer) { clearTimeout(timer) } timer = setTimeout(() => { func.apply(this, args) }, ms) } } // 测试
const task = () => { console.log('run task') } const debounceTask = debounce(task, 1000) window.addEventListener('scroll', debounceTask)

 

函数节流:函数在一段时间内只能被触发一次,如果这段时间内被触发多次,则只有一次生效,即每隔一段时间执行一次,也就是降低频率,将高频操作优化成低频操作。应用场景为滚动条事件或窗口resize事件,通常每隔100-500ms执行一次。简而言之,就是在滚动条请求时使用节流。

function throttle(func, ms = 1000) { let canRun = true
  return function (...args) { if (!canRun) return canRun = false setTimeout(() => { func.apply(this, args) canRun = true }, ms) } } // 测试
const task = () => { console.log('run task') } const throttleTask = throttle(task, 1000) window.addEventListener('scroll', throttleTask)

 

防抖或节流一般使用:

import debounce from 'lodash/debounce' debounce(()=>search(value), 500)

 

在类组件中使用防抖或节流:

import React from 'react'; import ReactDOM from 'react-dom'; import 'antd/dist/antd.css'; import { Input } from 'antd'; import throttle from 'lodash/debounce'; class Search extends React.Component { constructor(props) { super(props) this.handleSearch = throttle(this.handleOnChange, 200); } handleOnChange = (e) => { console.log(e.target.value) } render() { return ( <Input onChange={this.handleSearch} />
 ) } } ReactDOM.render( <Search />,
  document.getElementById('container'), );

 

在函数组件中使用防抖或节流,需要使用useCallback或useRef缓存变量和方法:

import React, { useCallback } from 'react'; import ReactDOM from 'react-dom'; import 'antd/dist/antd.css'; import { Input } from 'antd'; import debounce from 'lodash/debounce'; import throttle from 'lodash/throttle'; const Search = () => { const handleOnChange = (e) => { console.log(e.target.value) } const handleSearch = useCallback(throttle((e) => handleOnChange(e), 500), []) return (<Input onChange={handleSearch}  placeholder="Basic usage" />)
} ReactDOM.render(<Search />, document.getElementById('container'));

import React, { useRef } from 'react'; import ReactDOM from 'react-dom'; import 'antd/dist/antd.css'; import { Input } from 'antd'; import debounce from 'lodash/debounce'; import throttle from 'lodash/throttle'; const Search = () => { const handleOnChange = (e) => { console.log(e.target.value) } const handleSearch = useRef(throttle((e) => handleOnChange(e), 500)).current return (<Input onChange={handleSearch}  placeholder="Basic usage" />)
} ReactDOM.render(<Search />, document.getElementById('container'));

 

在函数组件里使用debounce,不使用lodash:

import { useEffect } from 'react'
function useDebounce(fn, delay, dep=[]) { useEffect(()=>{ let timer; timer = setTimeout(fn, delay); return ()=>clearTimeout(timer); }, [...dep] ) } export default useDebounce // 调用
useDebounce(()=>search(value), 500, [value])

import { useRef } from 'react'
function useDebounce(fn, delay) { const timer = useRef(null); return () => { clearTimeout(timer.current); timer.current = setTimeout(fn, delay); } } export default useDebounce // 调用
const debounceSearch = useDebounce(() => handleParams(params), 500) useEffect(()=>{debounceSearch()},[value]

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM