React 函数式组件中使用防抖节流不生效?

您所在的位置:网站首页 防抖失效 React 函数式组件中使用防抖节流不生效?

React 函数式组件中使用防抖节流不生效?

2023-09-15 06:09| 来源: 网络整理| 查看: 265

在 class 组件中使用防抖/节流,通常使用 debounce/ throttle 包裹需要防抖/节流的函数,即可创建一个防抖或节流的函数:

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 ( ) } } ReactDOM.render( , document.getElementById('container'), );

当我们在函数式组件中使用防抖/节流函数时,也会自然而然地使用 debounce/ throttle 包裹需要防抖/节流的函数:

import React 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 = throttle((e) => handleOnChange(e), 500) return () } ReactDOM.render(, document.getElementById('container'));

却发现做了防抖节流的函数并没有发挥作用,而是仅仅把时间延后了500毫秒而已。这是因为函数式组件每次渲染结束后,内部的变量都会被释放,重新渲染时所有的变量都会被重新初始化,产生的结果就是每一次都注册和执行了 setTimeout 函数。想要得到正确的运行结果,必须以某种方式存储那些会被删除的变量和方法的引用,遗憾的是没办法直接使用 useState 这个 hook 去存储。那么我们通过什么方式存储呢?欣慰的是,useCallback 和 useRef 这两个 hook 可以解决我们的问题。

useCallback

当把一个回调函数以依赖项数组作为参数传入 useCallback,它将返回一个缓存后的函数。

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')); useRef

useRef 返回一个可变的 ref 对象,其 .current 属性被初始化为传入的参数(initialValue)。返回的 ref 对象梓组件的整个生命周期内保持不变。

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'));



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3