You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用React Query v5库优化搜索查询处理?

优化React Query搜索功能的查询处理方案

针对你当前的React Query搜索实现,以下是几个实用的优化方向,既能减少服务器请求频次,又能提升用户体验:

1. 修复URL参数同步的异步问题

你当前的handleInputChange中,navigate使用的是旧的search状态值(因为setSearch是异步更新),会导致URL参数和输入框内容不同步。修改方式如下:

const handleInputChange = (e) => {
  const newValue = e.target.value;
  setSearch(newValue);
  // 使用encodeURIComponent处理特殊字符,避免URL解析错误
  navigate(`/appointments?search=${encodeURIComponent(newValue)}`);
};

2. 优化防抖逻辑与请求触发时机

当前已使用防抖,但可以进一步优化请求触发的条件,避免无效请求:

  • 添加搜索词长度阈值:比如仅当搜索词长度≥2时才发起请求,减少短关键词的无效请求
  • 用useEffect包裹focus逻辑:避免每次组件render都执行focus操作

修改useGetAppointmentsSearch hook:

export function useGetAppointmentsSearch({
  search,
  debounce = 1000, // 可适当缩短防抖时长,平衡体验和请求量
  inputRef,
}) {
  const debouncedSearchQuery = useDebounce(search, debounce);
  
  // 仅在组件挂载时执行focus
  useEffect(() => {
    if (inputRef.current) {
      inputRef.current.focus();
    }
  }, [inputRef]);

  // 仅当搜索词为空或长度≥2时触发请求
  const shouldFetch = debouncedSearchQuery === "" || debouncedSearchQuery.length >= 2;

  const query = useQuery({
    queryKey: ["appointments", debouncedSearchQuery ?? ""],
    queryFn: () => getAppointmentsSearchAsync({ search: debouncedSearchQuery }),
    keepPreviousData: true,
    enabled: shouldFetch, // 控制请求是否触发
    staleTime: 5000, // 5秒内数据视为新鲜,避免重复请求
    retry: 1, // 失败后重试1次,提升容错性
  });

  return query;
}

3. 规范API请求的URL拼接

当前手动拼接URL容易出错,改用URLSearchParams处理参数,更安全可靠:

async function getAppointmentsSearchAsync({ search }) {
  const url = new URL("/appointment/search", window.location.origin);
  if (search) {
    url.searchParams.set("appointmentSearch", search);
  }
  const { data } = await authFetch(url.toString());
  return data;
}

4. 优化URL参数与组件状态的同步

改用React Router的useSearchParams钩子替代直接操作location,状态同步更精准:

import { useSearchParams } from "react-router-dom";

const SearchPage = () => {
  const [search, setSearch] = useState("");
  const inputRef = useRef(null);
  const navigate = useNavigate();
  const [searchParams] = useSearchParams();
  const { data, error, status } = useGetAppointmentsSearch({
    search,
    inputRef,
  });

  useEffect(() => {
    const querySearchTerm = searchParams.get("search");
    // 仅当URL参数与当前state不一致时更新,避免重复渲染
    if (querySearchTerm !== search) {
      setSearch(querySearchTerm || "");
    }
  }, [searchParams, search]);

  // ... 其余代码不变
};

5. 增强空搜索场景的处理

当搜索词为空时,若后端返回全量数据,可通过React Query的缓存机制复用数据,避免重复请求;同时在UI上可以给出更清晰的提示:

// 在SearchPage的渲染逻辑中
return (
  <div className="appointment-list search-list">
    {status === "pending" ? (
      <Loader />
    ) : status === "error" ? (
      <span>Error: {error.message}</span>
    ) : data?.appointments ? (
      data.appointments.length > 0 ? (
        data.appointments.map((appointment) => (
          // 建议使用appointment的唯一ID作为key,而非index
          <AppointmentItem key={appointment.id} {...appointment} />
        ))
      ) : (
        <h3>{search ? "未找到匹配的预约数据" : "暂无预约数据"}</h3>
      )
    ) : (
      <h3>加载数据失败</h3>
    )}
  </div>
);

内容的提问来源于stack exchange,提问作者codercret company

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 06:45:58