如何在 React 中实现防抖(debounce)的搜索输入框?

如何在 React 中实现防抖(debounce)的搜索输入框?

回答与解析:

在 React 中实现防抖搜索输入框,通常是为了避免用户每输入一个字符就立即触发搜索请求,从而减少不必要的 API 调用、提升性能。可以通过自定义 hook 或使用第三方库(如 lodash.debounce)来实现。

示例代码(使用 lodash):

import React, { useState, useEffect } from 'react';
import debounce from 'lodash.debounce';

function SearchInput() {
  const [query, setQuery] = useState('');

  // 定义搜索函数
  const performSearch = (value) => {
    console.log('Searching for:', value);
    // 实际中这里会调用 API
  };

  // 使用 debounce 包装搜索函数
  const debouncedSearch = React.useMemo(
    () => debounce(performSearch, 300),
    []
  );

  useEffect(() => {
    // 当 query 变化时触发 debounced 搜索
    debouncedSearch(query);

    // 清理函数:组件卸载或 debounce 函数更新时取消 pending 的调用
    return () => {
      debouncedSearch.cancel();
    };
  }, [query, debouncedSearch]);

  return (
    <input
      type="text"
      placeholder="Search..."
      value={query}
      onChange={(e) => setQuery(e.target.value)}
    />
  );
}

export default SearchInput;

关键点解析:

  1. useMemo:确保 debounce 函数在整个组件生命周期内保持引用一致,避免每次渲染都创建新的 debounce 实例。
  2. useEffect + cleanup:在依赖项(query)变化时触发防抖函数,并在组件卸载或 effect 重新执行前取消未完成的调用,防止内存泄漏或无效状态更新。
  3. 防抖 vs 节流:防抖适用于“只关心最终结果”的场景(如搜索),节流适用于“定期执行”的场景(如滚动监听)。

若不想引入 lodash,也可自行实现简单的 debounce 函数:

function debounce(func, delay) {
  let timeoutId;
  return (...args) => {
    clearTimeout(timeoutId);
    timeoutId = setTimeout(() => func(...args), delay);
  };
}

但注意自行实现时需处理好闭包和 this 上下文问题,生产环境推荐使用经过充分测试的工具库。

发表评论 (审核通过后显示评论):

昵称:
邮箱:
内容: