Reactjs 下拉过滤器的用户输入onKeyUp上的去抖动或节流

Reactjs 下拉过滤器的用户输入onKeyUp上的去抖动或节流,reactjs,react-hooks,Reactjs,React Hooks,我正在尝试在搜索字段上为下拉过滤器对用户输入执行反弹跳和限制 我不熟悉钩子,我曾在构造函数中取消类组件的onChange函数的反弹,但由于一些奇怪的原因,钩子方法似乎不适合我 我尝试了很多东西,参考了网上的一些帖子。有目标值为null的问题,修复了这个问题,但我觉得它根本不想去反弹或限制用户输入 我确实在keyup={e=>debounce(func,2000)}上直接使用了它,但在e为null时存在问题 请参考()了解我想要实现的目标 import React, {useState, useE

我正在尝试在搜索字段上为下拉过滤器对用户输入执行反弹跳和限制

我不熟悉钩子,我曾在构造函数中取消类组件的onChange函数的反弹,但由于一些奇怪的原因,钩子方法似乎不适合我

我尝试了很多东西,参考了网上的一些帖子。有目标值为null的问题,修复了这个问题,但我觉得它根本不想去反弹或限制用户输入

我确实在keyup={e=>debounce(func,2000)}上直接使用了它,但在e为null时存在问题

请参考()了解我想要实现的目标

import React, {useState, useEffect} from 'react';
import './dropdownfilter.css';

function DropDownFilter() {

    const [options, setOptions] = useState(['Mytidbit', 'Deepak', 'Wassup', 'Deeps', 'Maolins', 'Test']);

    const [show, setShow] = useState(false);

    const [deBounce, setDebounce] = useState(true);

    const debounce = (fn,delay) => {
        let timeId;
        return function(...args){
            if(timeId){
                clearTimeout(timeId);
            }

            timeId = setTimeout(()=>{
                fn(...args);
            }, delay);
        }
    };

    function throttle(fn, delay){
        let last = 0;

        return (...args)=>{
         const now = new Date().getTime();
         if(now-last < delay){
             return;
         }

          last = now;
          return fn(...args);
        }
     }

    const filterOptions = (e)=>{
        const optionsCopy = [...options];
        let filteredOptions = optionsCopy.filter(opt=>opt.toLowerCase().includes(e.target.value.toLowerCase()));
        setOptions(filteredOptions);
    };

    const debounceKeyUp = (e) => {
        e.persist();
        filterOptions(e);    
    };

    const throttleKeyUp = (e)=>{
         e.persist();
         filterOptions(e);
    };

    useEffect(()=>{
       debounce(debounceKeyUp, 2000);
       throttle(throttleKeyUp, 2000);
    },[]);

    const displayFilter = () => {
         setShow(!show);
    };

    const toggleFilter = ()=>{
        setDebounce(!deBounce)
    };

    return (
        <div className="dropdown">
            <button className="dropbtn" onClick={toggleFilter}>Change Filter Type</button><br/>
            <button onClick={displayFilter} className="dropbtn">{deBounce ? "DeBounce" : "Throttle"} <i className="arroww downn"></i></button>
            <div className={`dropdown-content ${show ? "show" : "hide"}`}>
                <input type="text" placeholder={deBounce ? "Try Debounce..." : "Try Throttle..."} className="filter-input" onKeyUp={deBounce ? e => {e.persist(); debounceKeyUp(e)} : e => {e.persist(); throttleKeyUp(e)}} />
                <i className="fa fa-fw fa-search" style={{position: 'relative', bottom: '34px', left: '5px'}}></i>
                {options.map((opt, i)=>(
                    <a key={i}>{opt}</a>
                ))}
            </div>
        </div>
    )
}

export default DropDownFilter;
import React,{useState,useffect}来自“React”;
导入“./dropdownfilter.css”;
函数DropDownFilter(){
const[options,setOptions]=useState(['Mytidbit','Deepak','Wassup','Deeps','Maolins','Test']);
const[show,setShow]=useState(false);
常数[deBounce,setDebounce]=useState(真);
常数去盎司=(fn,延迟)=>{
让timeId;
返回函数(…args){
if(timeId){
clearTimeout(timeId);
}
timeId=setTimeout(()=>{
fn(…args);
},延误);
}
};
节气门功能(fn,延迟){
设last=0;
返回(…参数)=>{
const now=new Date().getTime();
如果(现在最后一次<延迟){
返回;
}
最后=现在;
返回fn(…args);
}
}
常数过滤器选项=(e)=>{
常量选项复制=[…选项];
让filteredOptions=optionsCopy.filter(opt=>opt.toLowerCase()。包括(e.target.value.toLowerCase());
设置选项(过滤选项);
};
常数衰减键控=(e)=>{
e、 坚持();
过滤选项(e);
};
常数throttleKeyUp=(e)=>{
e、 坚持();
过滤选项(e);
};
useffect(()=>{
去盎司(debounceKeyUp,2000年);
节流阀(节流阀,2000年);
},[]);
常量显示过滤器=()=>{
设置显示(!show);
};
常量切换过滤器=()=>{
设置反盎司(!反盎司)
};
返回(
更改过滤器类型
{deBounce?“deBounce”:“Throttle”} {e.persist();debounceKeyUp(e)}:e=>{e.persist();throttleKeyUp(e)}/> {options.map((opt,i)=>( {opt} ))} ) } 导出默认下拉过滤器;
要使用它们,您需要获得解盎司和节流功能的实例。不幸的是,您只是在useEffect中调用debounce和throttle,但从未使用它们返回的函数

您的实现不需要useEffect,但需要useCallback,如下所示

const debounceKeyUp = useCallback(debounce((e)=>{
     e.persist();
     filterOptions(e);
}, 2000), []);

const throttleKeyUp = useCallback(throttle((e)=>{
     e.persist();
     filterOptions(e);
}, 2000), []);
完整代码:

函数下拉过滤器(){
const[options,setOptions]=useState(['Mytidbit','Deepak','Wassup','Deeps','Maolins','Test']);
const[show,setShow]=useState(false);
常数[deBounce,setDebounce]=useState(真);
常数去盎司=(fn,延迟)=>{
让timeId;
返回函数(…args){
if(timeId){
clearTimeout(timeId);
}
timeId=setTimeout(()=>{
fn(…args);
},延误);
}
};
节气门功能(fn,延迟){
设last=0;
返回(…参数)=>{
const now=new Date().getTime();
如果(现在最后一次<延迟){
返回;
}
最后=现在;
返回fn(…args);
}
}
常数过滤器选项=(e)=>{
常量选项复制=[…选项];
让filteredOptions=optionsCopy.filter(opt=>opt.toLowerCase()。包括(e.target.value.toLowerCase());
设置选项(过滤选项);
};
const debounceKeyUp=useCallback(去盎司((e)=>{
e、 坚持();
过滤选项(e);
}, 2000), []);
const throttleKeyUp=useCallback(throttle((e)=>{
e、 坚持();
过滤选项(e);
}, 2000), []);
常量显示过滤器=()=>{
设置显示(!show);
};
常量切换过滤器=()=>{
设置反盎司(!反盎司)
};
返回(
更改过滤器类型
{deBounce?“deBounce”:“Throttle”} {e.persist();debounceKeyUp(e)}:e=>{e.persist();throttleKeyUp(e)}/> {options.map((opt,i)=>( {opt} ))} ) } 导出默认下拉过滤器;
是有道理……我没有使用反弹跳或油门的参考。这解决了我的问题…谢谢…我很高兴能帮上忙