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

React后端驱动表格搜索/筛选功能实现问题求助

解决React + GraphQL搜索/筛选功能问题

问题背景

作为React新手,尝试在项目中实现搜索/筛选功能,使用两个GraphQL API:GET_ALL_USERS获取所有用户作为表格默认内容,SEARCH_USERS根据输入的用户名或名称匹配后端用户。但实际效果不符合预期。

期望效果

  • 输入内容后点击搜索按钮,表格渲染搜索结果
  • 搜索无结果时,显示「未找到包含[输入内容]的用户」
  • 点击清空按钮后,表格恢复显示所有用户
  • 数据库中无用户时,显示「未找到用户」

当前问题

  • 输入内容时未点击搜索按钮就实时触发搜索
  • 搜索无结果时表格仍显示所有用户,未显示对应提示

原代码

import { useQuery } from "@apollo/client";
import { GET_ALL_USERS, SEARCH_USERS } from "../graphql/Queries";
import { useState } from 'react';

const UsersTable = () => {

  const [search, setSearch] = useState('')

  const{ data, error, loading } = useQuery(GET_ALL_USERS)
  const{ data: searchedData, error: searchedError, loading:searchedLoading } = useQuery(SEARCH_USERS, {
    variables: { name: search || null }
  })

  const searchedResult = searchedData ? searchedData.searchedUsers : []

  const masterData =(searchedResult && searchedResult.length > 0) ? searchedResult : data?.allUsers


 const handleSubmit = (e: any)=>{

 }


return(
   <div>
          {/* search */}
         <div>
            <input type="text" placeholder='Search for user' onChange={e => setSearch(e.target.value)}/>
            <button onSubmit={handleSubmit}>Search</button> 
        </div>

        
       {/*table*/}
    <table className="w-full text-left">
        <thead>
            <tr>
                <th>
                    Name
                </th>
                <th>
                    Username
                </th>
                <th>
                    Age
                </th>
            </tr>
        </thead>
        <tbody>
          {masterData && masterData.map((user: any)=>{
            return (
              <tr key={user.id}>
                  <th>
                    {user.name}
                  </th>
                  <td>
                    {user.username}
                  </td>
                  <td>
                    {user.age}
                  </td>
              </tr>                                                 
            )
          })}
        </tbody>
    </table>

   </div>
)
}

解决方案

关键修改点

  1. 控制搜索触发时机

    • 新增searchQuery状态,仅在点击搜索按钮时赋值,作为SEARCH_USERS的查询变量,避免输入时实时触发请求
    • 给SEARCH_USERS添加skip选项,当searchQuery为空时跳过查询,减少无用请求
  2. 修正数据逻辑与状态提示

    • 明确区分「未搜索」「搜索无结果」「无用户」三种场景,分别处理显示内容
    • 搜索无结果时,不再回退显示所有用户,而是展示对应提示文本
  3. 添加清空功能

    • 新增清空按钮,点击后重置输入框和搜索状态,恢复显示全部用户

修改后的完整代码

import { useQuery } from "@apollo/client";
import { GET_ALL_USERS, SEARCH_USERS } from "../graphql/Queries";
import { useState } from 'react';

const UsersTable = () => {
  // 输入框实时值
  const [search, setSearch] = useState('');
  // 待提交的搜索关键词,控制查询触发
  const [searchQuery, setSearchQuery] = useState('');

  const { data: allUsersData, error: allUsersError, loading: allUsersLoading } = useQuery(GET_ALL_USERS);
  const { data: searchedData, error: searchedError, loading: searchedLoading } = useQuery(SEARCH_USERS, {
    variables: { name: searchQuery },
    // 搜索关键词为空时跳过查询
    skip: !searchQuery
  });

  const allUsers = allUsersData?.allUsers || [];
  const searchedUsers = searchedData?.searchedUsers || [];

  // 处理表单提交,触发搜索
  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    setSearchQuery(search.trim());
  };

  // 清空搜索状态
  const handleClear = () => {
    setSearch('');
    setSearchQuery('');
  };

  return (
    <div>
      {/* 搜索区域 */}
      <form onSubmit={handleSubmit}>
        <input
          type="text"
          placeholder='Search for user'
          value={search}
          onChange={e => setSearch(e.target.value)}
        />
        <button type="submit">Search</button>
        {/* 清空按钮 */}
        {searchQuery && <button type="button" onClick={handleClear}>清空</button>}
      </form>

      {/* 加载状态提示 */}
      {(allUsersLoading || searchedLoading) && <p>加载中...</p>}

      {/* 错误提示 */}
      {(allUsersError || searchedError) && <p>加载用户失败,请稍后重试</p>}

      {/* 表格区域 */}
      <table className="w-full text-left">
        <thead>
          <tr>
            <th>Name</th>
            <th>Username</th>
            <th>Age</th>
          </tr>
        </thead>
        <tbody>
          {/* 场景1:未执行搜索,显示所有用户 */}
          {!searchQuery && allUsers.length > 0 && allUsers.map((user: any) => (
            <tr key={user.id}>
              <td>{user.name}</td>
              <td>{user.username}</td>
              <td>{user.age}</td>
            </tr>
          ))}

          {/* 场景2:执行了搜索,有结果则显示 */}
          {searchQuery && searchedUsers.length > 0 && searchedUsers.map((user: any) => (
            <tr key={user.id}>
              <td>{user.name}</td>
              <td>{user.username}</td>
              <td>{user.age}</td>
            </tr>
          ))}

          {/* 场景3:搜索无结果 */}
          {searchQuery && searchedUsers.length === 0 && (
            <tr>
              <td colSpan={3} style={{ textAlign: 'center' }}>
                未找到包含「{searchQuery}」的用户
              </td>
            </tr>
          )}

          {/* 场景4:数据库无任何用户 */}
          {!searchQuery && allUsers.length === 0 && (
            <tr>
              <td colSpan={3} style={{ textAlign: 'center' }}>
                未找到用户
              </td>
            </tr>
          )}
        </tbody>
      </table>
    </div>
  );
};

export default UsersTable;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 01:50:00