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

使用RTK Query+React+Material UI实现商品搜索过滤遇错求助

商品搜索过滤功能修复

问题描述

使用fakestoreapi实现商品搜索过滤,输入框能获取值但功能失效,控制台抛出Uncaught TypeError: Cannot read properties of undefined (reading 'filter')错误,根源是API请求未完成时data为undefined,直接调用filter方法导致报错。

修复方案

1. 增加API状态判断

在渲染搜索结果前,先判断数据是否加载完成,避免在data为undefined时执行过滤逻辑。

2. 优化过滤逻辑并缓存结果

用useMemo缓存过滤后的结果,避免每次渲染都重复执行过滤操作,同时给data添加空值兜底。

3. 调整组件传参方式

直接将过滤后的结果传给SearchResult组件,而非传递函数,简化组件逻辑。

修改后的代码

SearchInput.jsx

import React, { useState, useMemo } from 'react'
import { Box, TextField, InputAdornment, CircularProgress, Typography } from "@mui/material";
import SearchIcon from "@mui/icons-material/Search";
import { useGetAllProductsQuery } from '../../services/features/api/shopApiSlice';
import { SearchResult } from '../../components/Search';

export const SearchInput = () => {
    const [searchProduct, setSearchProduct] = useState("");
    const { data, error, isError, isLoading, isFetching } = useGetAllProductsQuery();

    const handleChangeSearch = (event) => {
        const { value } = event.target
        setSearchProduct(value);
    };

    // 用useMemo缓存过滤结果,仅当data或searchProduct变化时重新计算
    const filteredProducts = useMemo(() => {
        // 数据未加载时返回空数组
        if (!data) return [];
        return data.filter((product) => {
            return product.title.toLowerCase().includes(searchProduct.toLowerCase());
        });
    }, [data, searchProduct]);

    // 加载状态提示
    if (isLoading || isFetching) {
        return <CircularProgress />;
    }

    // 错误状态提示
    if (isError) {
        return <Typography color="error">加载商品失败:{error?.message}</Typography>;
    }

    return (
        <Box
            component="form"
            noValidate
        >
            <TextField
                type="search"
                size='small'
                sx={{
                    width: "100%",
                }}
                id="pesquisar-produto"
                placeholder="Pesquisar"
                value={searchProduct}
                onChange={handleChangeSearch}
                InputProps={{
                    startAdornment: (
                        <InputAdornment position="start">
                            <SearchIcon />
                        </InputAdornment>
                    )
                }}
            />
            <SearchResult products={filteredProducts}/>
        </Box>
    )
}

SearchResult.jsx

import React from 'react';
import { Box, Typography } from '@mui/material';

export const SearchResult = ({ products }) => {
    // 无匹配结果时提示
    if (products.length === 0) {
        return <Typography variant="body2">未找到匹配的商品</Typography>;
    }

    return (
        <Box>
            {products.map((product) => {
                return (
                    <Box key={product.id}>
                        <li>{product.title}</li>
                    </Box>
                );
            })}
        </Box>
    )
}

关键说明

  • 新增了加载和错误状态的UI提示,提升用户体验
  • 用useMemo缓存过滤结果,减少不必要的计算,优化性能
  • 给data添加了空值判断,彻底解决undefined.filter的报错问题
  • 调整了组件传参逻辑,让SearchResult组件更专注于渲染结果,职责更清晰

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 17:10:39