【问题标题】:Debounce not working when setting state inside of it在其中设置状态时去抖动不起作用
【发布时间】:2019-07-28 12:54:19
【问题描述】:

执行自动完成的组件。 当输入一个 API 请求时,我添加了一个去抖动器。 在 debouncer 中设置 inputValue 时,debouncer 不会执行。

const SearchComp  = ({
    autoCompleteRes,
    classes,
    currCondtionsForSelectedAction, 
    forecastForSelectedAction, 
    searchAction,
      }) => {
    const [ inputValue, setInputValue] = useState('Tel aviv')

    const changeText = (e) => {
        const searchTerm = e.target.value.trim()
        if( searchTerm === ('' || undefined)) {
            clearSearchAction()
            return
        } 
        searchAction(searchTerm)
    }

     const debounce = (func) => {
        let debouncerTimer;
        return function(e){
            setInputValue(e.target.value) // if i comment this line 
            const context = this;
            const args = arguments;
            clearTimeout(debouncerTimer);
            e.persist()
            debouncerTimer = setTimeout(() => {
                return func.apply(context,args)},1500)
        }
    }

    const onClickedRes = (selected) => {
        setInputValue(`${selected.LocalizedName}, ${selected.AdministrativeArea.LocalizedName} ${selected.Country.LocalizedName}`)
        forecastForSelectedAction(selected);
        currCondtionsForSelectedAction(selected);
    }

    return (
            <div className={classes.root}>
                <div className={classes.inputWrapper}>

                    <input type="text" className={classes.inputStyle} name="firstname" 
                        value={inputValue} // and comment this line the debouncer works
                        onChange={debounce(changeText)} 
                    />
                    <div className={classes.dropDownContent}>
                      {autoCompleteRes.map(item => (
                          <div 
                            key={item.Key} 
                            className={classes.autoCompleteSingleRes} 
                            onClick={() =>  onClickedRes(item) }
                          >
                             {`${item.LocalizedName}, ${item.AdministrativeArea.LocalizedName} ${item.Country.LocalizedName}`}
                         </div>))}
                    </div>
                </div>
            </div>
        )
;}

我不是一次调用 changeText 函数,而是调用每一次键盘敲击。

不知道发生了什么以及如何解决它。

谢谢

【问题讨论】:

    标签: reactjs input debounce


    【解决方案1】:

    通过将 debounce 函数放在函数式组件中,它会在每次渲染时重新创建函数(每次击键都会导致重新渲染),并将新创建的 debounce 函数应用于 changeText

    您可以在这里采取几种方法:

    1) 将 debounce 函数移到组件之外,使其在渲染之间是幂等的。这意味着您将 setInputValue 等放入传递给 debounce 的 func 参数中,因为它们现在不在范围内。

    2) 将 debounce 函数包装在 React.useCallback 中,这将记住 debounce,因此它不会在渲染之间发生变化,除非它依赖的依赖项发生变化 (setinputValue)。

    【讨论】:

    • 1) 不会将正确的值传递给输入字段,因为 funcsetTimeout 内部被调用,只有在 setTimeout 完成后才会调用 setInputValue ---- -------------------------------------------------- ------------------ 2)我尝试使用它,但也许我错过了一些东西。因为它没有任何效果。 useCallback((func) =&gt; { ... debouncerTimer = setTimeout(() =&gt; { return func.apply(context,args)},1500) } }, [])
    猜你喜欢
    • 2021-10-26
    • 2015-10-19
    • 1970-01-01
    • 2013-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-09
    • 1970-01-01
    相关资源
    最近更新 更多