Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 在onChange函数中使用时超时未清除_Reactjs_Settimeout - Fatal编程技术网

Reactjs 在onChange函数中使用时超时未清除

Reactjs 在onChange函数中使用时超时未清除,reactjs,settimeout,Reactjs,Settimeout,我正在为我正在开发的网站创建搜索功能。当用户键入关键字时,将发送get请求以检索匹配信息。然而,每次按下一个键就让它开火感觉非常浪费。假设用户想要搜索三明治,他们很可能会很快连续输入,我只想在用户停止输入后的一段时间内(比如250毫秒)启动它。我的想法是设置一个超时,它将在连续的击键时被清除。不幸的是,超时没有重置,只是被延迟了。我尝试将它放在useEffect挂钩中,然后超时工作正常,但我遇到了一些其他问题,这促使我尝试以这种方式执行 const onChangeBrand = (e)

我正在为我正在开发的网站创建搜索功能。当用户键入关键字时,将发送get请求以检索匹配信息。然而,每次按下一个键就让它开火感觉非常浪费。假设用户想要搜索三明治,他们很可能会很快连续输入,我只想在用户停止输入后的一段时间内(比如250毫秒)启动它。我的想法是设置一个超时,它将在连续的击键时被清除。不幸的是,超时没有重置,只是被延迟了。我尝试将它放在useEffect挂钩中,然后超时工作正常,但我遇到了一些其他问题,这促使我尝试以这种方式执行

    const onChangeBrand = (e) => {
        const brand = e.target.value
        setBrand(brand)
        const timeout = setTimeout(()=>{
            url.get(`brands?search=${encodeURI(brand.toLowerCase())}&rows=5`)
                .then(res => {
                    setBrands(res.data)
                    if(res.data.length === 1 && res.data[0].urlEncoding === encodeURI(brand.toLowerCase())){
                        setPageType("models")
                    }else{
                        setPageType("brands")
                    }
                })
        },2500)
        return () => clearTimeout(timeout);
    }

任何帮助都将不胜感激

你的想法是对的,但执行错误。从
onChange
处理程序返回函数本质上没有任何作用–这在
useffect
中可以正常工作,所以我知道它是从哪里来的。这种模式被称为函数,有大量的预制库可以帮助您限制函数(比如),但是自己编写函数是非常酷的

这里的关键是:

  • 使用作用域在方法外部的超时变量
  • 在开始执行
    onChange
    时,检查超时变量是否有值–如果有,请清除它
  • 执行
    onChange
    ,分配新的超时时间
  • 您可以在这里使用
    ref
    或其他东西,但我个人认为在组件范围之外定义超时保持器是最容易的

    let CHANGE_TIMEOUT = null;
    
    function MyComponent(props) {
    
    // .. component code
    
        const onChangeBrand = (e) => {
            if (CHANGE_TIMEOUT) {
              // we already have a previous timeout, clear it.
              clearTimeout(CHANGE_TIMEOUT);
            }
    
            const brand = e.target.value
            setBrand(brand)
    
            // Set the timeout again
            CHANGE_TIMEOUT = setTimeout(()=>{
                url.get(`brands?search=${encodeURI(brand.toLowerCase())}&rows=5`)
                    .then(res => {
                        setBrands(res.data)
                        if(res.data.length === 1 && res.data[0].urlEncoding === encodeURI(brand.toLowerCase())){
                            setPageType("models")
                        }else{
                            setPageType("brands")
                        }
                    })
            },2500);
          }
    
    // .. other component code here
    
    }
    

    我不确定simple函数的工作原理是否与useEffect相同。它不会在后期渲染页面上触发。这是完美的!非常感谢你!我还有一个问题,如果你不介意的话,你认为对于这样一个函数,一个合适的超时应该是什么?我相信我在某个地方读到过250ms是一个不错的数字,但我很想听听你的想法。在过去,我在我们的用户体验团队的建议下使用了
    500ms
    ——有一个神奇的范围,可以让体验保持快速、高性能,而且不会像应用程序坏了一样。太棒了!谢谢,我试试看。非常感谢你的帮助!