React处理自动完成,等待一段时间来加载动态数据。

12 浏览
0 Comments

React处理自动完成,等待一段时间来加载动态数据。

这个问题已经有答案了:

如何执行抖动函数?

我有一个自动补全组件,初始时没有要显示的数据。当用户输入时,它会动态加载数据。但是我希望当用户停止输入时才进行加载,而不是每次迅速输入时都加载。因此,我会等待1500毫秒,然后检查字符串是否已更改。但是代码并没有按照我预期的那样工作。

const dispatch = useDispatch();
const [searchStr, setSearchStr] = useState(null);
function handleChange(event) {
    const str = event.target.value.toLowerCase();
    if (str.length < 2) return; setSearchStr(str); setTimeout(() => {
      // str never equals searchStr
      console.log(str, searchStr)
      if(str === searchStr) {
         dispatch(doSearch(searchStr));
      }
    }, 1500);
}

admin 更改状态以发布 2023年5月23日
0
0 Comments

你的代码中存在两个问题。

1- setState 是异步运行的,所以setSearchStr 不会立即更改searchStr的值。

2- 每次输入更改时,都会创建一个新的setTimeout,所以从第一个字符开始输入1500毫秒后,它将失去作用。你要做的事情叫做防抖。解决方法是在创建新的setTimeout之前清除以前的setTimeout

let timer; // =========> HERE
function MyComponent() {
  const dispatch = useDispatch();
  const [searchStr, setSearchStr] = useState(null);
  function handleChange(event) {
    const str = event.target.value.toLowerCase();
    if (str.length < 2) return;
    setSearchStr(str);
    clearTimeout(timer); // =========> HERE
    timer = setTimeout(() => {
       dispatch(doSearch(str));
    }, 1500);
  }
}

如果你坚持要保存搜索值在有状态的变量中,你可以使用useEffect

let timer; // =========> HERE
function MyComponent() {
  const dispatch = useDispatch();
  const [searchStr, setSearchStr] = useState(null);
  function handleChange(event) {
    const str = event.target.value.toLowerCase();
    setSearchStr(str);
  }
  useEffect(() => {
    if (searchStr.length < 2) return;
    clearTimeout(timer);
    timer = setTimeout(() => {
       dispatch(doSearch(searchStr));
    }, 1500);
  }, [searchStr])
}

0