You need to enable JavaScript to run this app. React结合Laravel开发表格搜索 页面初始无数据需搜索后才显示如何解决
优惠活动
大模型
产品
解决方案
定价
更多

React结合Laravel开发表格搜索 页面初始无数据需搜索后才显示如何解决

实现页面初始加载全量患者数据

问题说明

当前组件仅在输入框内容变化时触发接口请求,初始状态data为空数组,且后端路由要求必须传入key参数,因此页面首次加载无默认展示数据。

可选实现方案


方案1:前端本地筛选(数据量较小时优先选用,性能更优)

该方案首次加载时一次性拉取全量数据,后续搜索直接在本地内存中匹配,无需每次输入都请求后端。

前端改动

首先引入React的useEffect钩子用于触发首次加载,新增原始全量数据的存储状态,修改搜索逻辑为本地筛选:

// 补充引入useEffect
import { useState, useEffect } from "react";

function SearchPatient() {
  // 存储表格展示数据
  const [data, setData] = useState([]);
  // 存储全量原始数据,避免搜索后原始数据丢失
  const [allPatients, setAllPatients] = useState([]);

  // 组件首次挂载时自动拉取全量数据
  useEffect(() => {
    async function loadAllPatients() {
      const res = await fetch("http://localhost:8000/api/search/");
      const resData = await res.json();
      setData(resData);
      setAllPatients(resData);
    }
    loadAllPatients();
  }, []); // 空依赖数组表示仅在组件首次加载时执行

  // 本地筛选处理函数
  function handleSearch(e) {
    const keyword = e.target.value.trim().toLowerCase();
    // 输入为空时直接展示全量数据
    if (!keyword) {
      setData(allPatients);
      return;
    }
    // 按姓名字段模糊匹配
    const filteredData = allPatients.filter(patient => 
      patient.nom.toLowerCase().includes(keyword)
    );
    setData(filteredData);
  }

  return (
    <div>
      <Container>
        <div className="form-group">
          <label htmlFor="exampleInputEmail1">Search</label>
          <input
            type="text"
            className="form-control"
            placeholder="Search"
            id="nom"
            onChange={handleSearch}
          />
        </div>
        {/* 表格部分代码保持原有逻辑不变 */}
        <Table className="table table-hover">
          <Thead className="thead-light text-center">
            <Tr>
              <Th>N°</Th>
              <Th style={{ width: "6%" }}>NOM</Th>
              <Th>PRÉNOM</Th>
            </Tr>
          </Thead>
          <Tbody className="text-center">
            {data.map((patient) => (
              <Tr>
                <Td style={{ verticalAlign: "middle" }} className="text-muted">
                  <b>{patient.id}</b>
                </Td>
                <Td style={{ verticalAlign: "middle" }}>{patient.nom} </Td>
                <Td style={{ verticalAlign: "middle" }}>{patient.prenom} </Td>
              </Tr>
            ))}
          </Tbody>
        </Table>
      </Container>
    </div>
  );
}

后端改动

将Laravel路由的key参数设为可选,控制器处理空参数时返回全量数据:

// 路由中给参数加? 标记为可选
Route::get('/search/{key?}/', [PatientController::class, 'search']);
public function search($key = null)
{
    // 无传入搜索关键词时返回全部患者数据
    if (!$key) {
        return Patient::all();
    }
    // 有关键词时执行原有模糊查询逻辑
    return Patient::where('nom','Like',"%$key%")->get();
}

方案2:保留后端实时搜索逻辑(数据量较大时选用)

如果不想改动原有搜索的后端请求逻辑,仅需在组件首次加载时主动触发一次空关键词的搜索,即可加载全量数据。

前端改动

仅需引入useEffect钩子,在组件挂载时主动调用一次search(''),原有逻辑全部保留:

// 补充引入useEffect
import { useState, useEffect } from "react";

function SearchPatient() {
  const [data, setData] = useState([]);

  async function search(key) {
    let result = await fetch("http://localhost:8000/api/search/" + key);
    result = await result.json();
    setData(result);
  }

  // 组件首次加载时主动触发空关键词搜索,拉取全量数据
  useEffect(() => {
    search('');
  }, []);

  return (
    // 原有JSX代码完全不变
    <div>
      <Container>
        <div className="form-group">
          <label htmlFor="exampleInputEmail1">Search</label>
          <input
            type="text"
            className="form-control"
            placeholder="Search"
            id="nom"
            onChange={(e) => search(e.target.value)}
          />
        </div>
        <Table className="table table-hover">
          <Thead className="thead-light text-center">
            <Tr>
              <Th>N°</Th>
              <Th style={{ width: "6%" }}>NOM</Th>
              <Th>PRÉNOM</Th>
            </Tr>
          </Thead>
          <Tbody className="text-center">
            {data.map((patient) => (
              <Tr>
                <Td style={{ verticalAlign: "middle" }} className="text-muted">
                  <b>{patient.id}</b>
                </Td>
                <Td style={{ verticalAlign: "middle" }}>{patient.nom} </Td>
                <Td style={{ verticalAlign: "middle" }}>{patient.prenom} </Td>
              </Tr>
            ))}
          </Tbody>
        </Table>
      </Container>
    </div>
  );
}

该方案的后端改动和方案1完全一致,无需额外调整。

注意事项

  • 方案1 适合数据量小于1000条的场景,本地筛选无需等待后端响应,搜索体验更流畅
  • 方案2 适合需要分页、复杂权限校验或数据量较大的场景,所有筛选逻辑仍由后端控制
  • 调整Laravel路由时需确保可选参数的标记?正确添加,否则会出现404错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.29 11:15:08