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

React搜索功能如何实现无匹配结果时显示「未找到结果」提示

React搜索无匹配结果提示实现方案

核心逻辑是在现有渲染分支中新增判断:当用户已输入搜索关键词、且过滤后的结果数组长度为0时,渲染无结果提示即可,同时顺手修复原代码存在的搜索状态异步bug(原代码setSearchInput后立刻读取旧状态,会导致搜索匹配延迟一个字符的问题)。


具体修改点

  • 修复searchItems函数的状态异步问题:函数内不要使用刚触发更新的searchInput状态做判断,直接使用入参searchValue做过滤逻辑判断和关键词匹配,避免搜索结果和输入不同步。
  • 调整结果区域渲染分支:原有逻辑仅判断「是否有搜索输入」,现在在「有输入」的分支下新增二级判断:如果过滤结果长度为0就渲染无结果提示,有结果再遍历渲染结果卡片。
  • (可选优化)补上原代码已经定义但未使用的加载状态、接口错误状态渲染,提升交互完整性。
  • 补全原代码缺失的初始赋值逻辑:接口拉取全量数据后,同步给filteredResults赋初始值,避免页面初次加载时结果区域空白。

修改后完整代码

import { useState, useEffect } from 'react';
import axios from 'axios';
import { OutlinedInput, InputAdornment } from '@mui/material';
import SearchIcon from '@mui/icons-material/Search';
import { Link } from 'react-router-dom';

export default function SearchInput() {

    const [APIData, setAPIData] = useState([]);
    const [searchInput, setSearchInput] = useState('');
    const [filteredResults, setFilteredResults] = useState([]);

    const [error, setError] = useState(false);
    const [isLoaded, setIsLoaded] = useState(false);
    
    useEffect(() => {
        const fetchData = async () => {
          setError(false);
          setIsLoaded(true);
    
          try{
            const response = await axios("/posts");
            setAPIData(response.data);
            // 初始拉取数据后给过滤结果赋默认值
            setFilteredResults(response.data);
          } catch(error) {
            setError(true);
            console.error(error);
          }
          setIsLoaded(false);
        };
        fetchData();
      }, []);
    
    const searchItems = (searchValue) => {
        setSearchInput(searchValue)
        // 修复:直接使用入参searchValue判断,避免状态异步导致的匹配延迟
        if (searchValue !== '') {
            const filteredData = APIData.filter((post) => {
                return Object.values(post).join('').toLowerCase().includes(searchValue.toLowerCase())
            })
            setFilteredResults(filteredData)
        }
        else{
            setFilteredResults(APIData)
        }
    }

    return (
        
        <div style={{ padding: 20 }}>
            
            <OutlinedInput 
                className="SearchInput"
                placeholder='Search...'
                onChange={(e) => searchItems(e.target.value)}
                endAdornment={
                    <InputAdornment position="end">
                    <SearchIcon />
                    </InputAdornment>
                }
            />

            <div style={{ marginTop: 20 }}>
                {/* 加载状态渲染 */}
                {isLoaded && <div>数据加载中...</div>}
                {/* 接口错误渲染 */}
                {error && <div>数据加载失败,请稍后重试</div>}
                {/* 数据加载完成且无报错时渲染主内容 */}
                {!isLoaded && !error && (
                    <>
                    {searchInput.length > 0 ? (
                        // 有搜索输入时的逻辑分支
                        filteredResults.length === 0 ? (
                            // 无匹配结果,渲染提示
                            <div style={{textAlign: 'center', color: '#666', padding: '40px 0'}}>
                                no results found(未找到结果)
                            </div>
                        ) : (
                            // 有匹配结果,遍历渲染卡片
                            filteredResults.map((post) => {
                                return (
                                    <div className="card" key={post._id}>
                                    <div className="card-content">
                                    <Link to={`/post/${post._id}`} className="link">
                                    <h2 className="results-title">
                                        {post.title}
                                    </h2>
                                    <ol className="card-username">
                                        {post.username}      
                                    </ol>
                                    </Link>
                                    </div>
                                </div>
                                )
                            })
                        )
                    ) : (
                        // 无搜索输入时,渲染全量数据
                        APIData.map((post) => {
                            return (
                                <article className="card" key={post._id}>
                                <div className="card-content">
                                <Link to={`/post/${post._id}`} className="link">
                                <h2 className="card-name">
                                    {post.title}
                                </h2>
                                <ol className="card-username">
                                    {post.username}      
                                </ol>
                                </Link>
                                </div>
                            </article>
                            )
                        })
                    )}
                    </>
                )}
            </div>
        </div>
    )
}

补充说明

无结果提示的样式可以根据项目设计规范自行调整,示例中仅写了基础的居中、灰色文字样式。如果不需要加载、错误状态的提示,可以直接删除对应判断分支,仅保留无搜索结果的判断逻辑即可。

内容的提问来源于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.27 20:48:21