Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JavaScript中的防抖与节流、在react class及hook中使用防抖与节流 - starlog - 博客园 #95

Open
HenryTSZ opened this issue Jan 26, 2024 · 0 comments

Comments

@HenryTSZ
Copy link
Owner

函数防抖:函数被触发后过一段时间再执行,如果在这段时间内又被触发,则重新计时,即将多次高频操作优化为只在最后一次执行。应用场景为用户连续输入,只需要在输入结束后做一次校验即可,比如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( ,
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 ()
}

ReactDOM.render(, 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 ()
}

ReactDOM.render(, 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]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant