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

React开发搜索功能时如何初始仅拉取5/10条接口数据

实现逻辑调整步骤

你需要从状态扩展、请求方法改造、交互绑定三个层面调整代码,前提是你的/posts后端接口支持分页条数、搜索关键词两个查询参数,否则前端无法单独实现按需拉取的效果。

  • 首先新增3个必要状态:搜索输入值、请求加载状态、防抖定时器实例,避免重复请求、频繁触发请求
  • 改造原有fetchData方法,支持接收搜索关键词、拉取条数两个入参,拼接到请求url上发给后端
  • 组件初始加载时,只请求10条(或5条)无关键词的默认数据
  • 给搜索框绑定输入事件,加300ms防抖:用户停止输入300ms后再发起搜索请求,输入清空时自动切回初始的10条默认数据
  • 渲染时加加载态提示,避免用户操作无反馈
改造后完整代码
import React, { useEffect, useState, useRef } from 'react';

const Table2 = () => {
  const [posts, setPosts] = useState([]);
  // 搜索关键词状态
  const [searchKey, setSearchKey] = useState('');
  // 加载状态
  const [loading, setLoading] = useState(false);
  // 防抖定时器ref
  const timerRef = useRef(null);

  /**
   * 拉取数据方法
   * @param {string} keyword 搜索关键词
   * @param {number} limit 拉取条数,默认初始拉10条
   */
  const fetchData = (keyword = '', limit = 10) => {
    setLoading(true);
    // 拼接查询参数
    const query = new URLSearchParams({
      limit,
      keyword
    }).toString();

    fetch(`/posts?${query}`)
      .then((response) => response.json())
      .then((data) => {
        setPosts(data);
      })
      .finally(() => {
        setLoading(false);
      });
  };

  // 初始加载默认10条数据
  useEffect(() => {
    fetchData();
  }, []);

  // 监听搜索输入,防抖触发搜索
  const handleSearchInput = (e) => {
    const value = e.target.value.trim();
    setSearchKey(value);
    // 清除上一次的定时器
    if (timerRef.current) clearTimeout(timerRef.current);
    // 300ms后发请求,搜索场景拉取足够多的匹配结果,无搜索词时回到默认10条
    timerRef.current = setTimeout(() => {
      fetchData(value, value ? 1000 : 10);
    }, 300);
  };

  return (
    <div>
      {/* 搜索输入框 */}
      <input
        type="text"
        placeholder="输入关键词搜索内容"
        value={searchKey}
        onChange={handleSearchInput}
        style={{ marginBottom: 12, padding: '6px 8px', width: 240 }}
      />
      <table>
        <tbody>
          <tr>
            <th>Name</th>
            <th>Surname</th>
          </tr>
          {loading ? (
            <tr>
              <td colSpan={2} style={{ textAlign: 'center' }}>加载中...</td>
            </tr>
          ) : posts.length ? (
            posts.map((post) => (
              <tr key={post._id}>
                <td>{post.title}</td>
                <td>{post.username}</td>
              </tr>
            ))
          ) : (
            <tr>
              <td colSpan={2} style={{ textAlign: 'center' }}>无匹配数据</td>
            </tr>
          )}
        </tbody>
      </table>
    </div>
  );
};

export default Table2;
注意事项
  • 必须和后端对齐接口参数:比如后端如果分页参数叫pageSize、搜索参数叫q,你需要把代码里的参数名改成和后端一致的,否则请求不生效
  • 如果需要更严谨的交互,可以加请求取消逻辑:用AbortController在上一个请求未完成时取消旧请求,避免先后返回的请求结果错乱
  • 防抖时长可以根据你的业务调整,一般200-300ms是体验比较好的区间,太短容易发太多无效请求,太长会让用户觉得输入反应慢

内容的提问来源于stack exchange,提问作者sultan.h

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 06:18:21