代码之家  ›  专栏  ›  技术社区  ›  ima.technophyle

反应:去盎司

  •  0
  • ima.technophyle  · 技术社区  · 5 年前

    考虑下面的反应代码。在这里,我试图在输入发生变化时添加去盎司功能。它按预期工作,即当有3000ms的延迟时,API调用也会发生。但问题是,, 假设我输入了4个字符,3000毫秒后,4个不同的API调用将发生,而不是1个。 为什么会这样,我现在做的有什么问题吗?当我删除下面提到的行时,问题就解决了。为什么呢?

    const [inputValue, setInputValue] = useState("");
    
    const getSearch = (val) => {
    
        axios.get("url")
             .then(({ data }) => {      
             }).catch( () => {
             })
    }    
    
    const holdSearch = (callback, delay) => {
        let clear;
        return function(...args) {
           clearTimeout(clear);
           clear = setTimeout(() => {
                       callback(args[0]);
                   }, delay);
        }
     }
    
    const makeSearch = holdSearch(getSearch, 3000);
    
    const handleChange = ({target}) => {
           
       setInputValue(target.value); // If I remove this statement, everything works as required
       makeSearch(target.value);
    
    }
    

    <input value = {inputValue} onChange = {handleChange} />
    
    1 回复  |  直到 5 年前
        1
  •  2
  •   Nicholas Tower    5 年前

    每次渲染组件时,您都会创建一个新的 makeSearch 作用这没什么不好的,只是这也意味着你有了一个全新的 clear clearTimeout(clear) 从不做任何事,因为 清楚的 始终是值为的全新变量 undefined

    您需要将该值从一个渲染粘贴到另一个渲染,这意味着使用 useRef

    const timerId = useRef();
    const holdSearch = (callback, delay) => {
      return function (...args) {
        clearTimeout(timerId.current);
        timerId.current = setTimeout(() => {
          callback(args[0]);
        }, delay);
      }
    }
    

    当我删除下面提到的行时,问题就解决了。为什么呢?

    如果不设置状态,则组件不会重新渲染,因此不会创建新变量。以后发生的任何onChangeEvents都将转到同一个handleChange函数和同一个makeSearch函数。