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