React搜索组件:实现无结果错误提示与结果数量展示
解决方案
核心思路是把过滤、排序后的结果单独存为变量,通过该变量的长度判断是否有匹配结果,以此展示对应的提示信息。同时修复原代码里的两个潜在问题:useEffect 缺少依赖项导致的无限请求,以及React元素属性误用class(需改为className)。
重构后的代码
import React, { useState, useEffect } from 'react'; import { useParams } from "react-router-dom"; import Helmet from 'react-helmet'; import axios from 'axios'; export default function Results() { const { id } = useParams(); const [rows, setRows] = useState([]); // 仅在组件挂载时请求一次全量数据,避免重复请求 useEffect(() => { axios.get('http://localhost:8080/products/get/') .then(res => { setRows(res.data); }).catch(err => { console.log(err); }); }, []); // 提前计算过滤、排序后的结果,方便复用 const filteredRows = rows .sort((a, b) => a.name.localeCompare(b.name)) .filter(row => row.name.toLowerCase().includes(id.toLowerCase())); return ( <> <Helmet> <title>website title | {id}</title> </Helmet> <div className="py-16 max-w-[1200px] mx-5 lg:mx-auto"> <h1 className="text-xl font-medium tracking-wide italic text-gray-400">Showing results for: {id}</h1> {/* 展示结果数量或无结果提示 */} <div className="mt-4 text-gray-600"> {filteredRows.length > 0 ? `找到 ${filteredRows.length} 条结果` : `没有找到与 "${id}" 匹配的产品`} </div> <div className="w-full flex space-x-10 mt-8"> <div className="w-1/4 p-5 rounded border"> sidebar </div> <div className="mt-5 w-3/4"> <div className="flex space-x-10"> <div className="border rounded">Sort by: </div> <div className="border rounded">Product per page:</div> </div> {/* 渲染过滤后的结果 */} {filteredRows.map((row, index) => ( <div key={index} className="mt-4"> <p>{row.name}</p> <img src={row.image} alt={`Image of ${row.name}`} className="w-[250px] h-auto" /> </div> ))} </div> </div> </div> </> ); };
关键改进点
- 提取过滤结果变量:把
rows.sort().filter()的结果赋值给filteredRows,既可以直接用来渲染列表,又能通过filteredRows.length判断结果状态,解决了原代码无法获取匹配数量的问题。 - 修复useEffect依赖:添加空数组
[]作为useEffect的依赖项,确保仅在组件首次挂载时请求数据,避免不必要的重复请求。 - 替换class为className:React元素中需使用
className替代HTML的class属性,消除控制台警告。 - 优化提示信息:根据
filteredRows.length动态展示结果数量或无匹配提示,符合需求场景。
内容的提问来源于stack exchange,提问作者Josh Haywood
相关产品推荐
相关产品推荐

