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

React实现API搜索栏时出现filter读取undefined错误求助

解决React搜索栏API数据过滤的TypeError问题

问题原因拆解

你遇到的TypeError: Cannot read properties of undefined (reading 'filter')以及过滤返回undefined的问题,根源在这几点:

  1. 错误的过滤目标:datum是API返回的数组,你错误地尝试调用datum.title?.filter()——数组本身没有title属性,所以datum.title是undefined,自然无法调用filter方法。
  2. 多余的异步处理:数组过滤是同步操作,你给handleFilter加了async/await,导致把普通数组当成Promise处理,最终返回undefined。
  3. 逻辑匹配偏差:原代码遍历元素所有属性做匹配,但实际需求是搜索食品名称,直接检查title属性更精准高效。

修复步骤与代码调整

1. 修正Filter组件的过滤逻辑

移除不必要的async/await,直接对datum数组进行过滤,同时明确针对title属性做匹配:

import { useState, useMemo } from "react"

function Filter({ datum }) {
  const [filterText, setFilterText] = useState("")

  const handleInput = (e) => {
    setFilterText(e.target.value)
  }

  // 使用useMemo缓存过滤结果,避免每次渲染重复计算
  const filteredData = useMemo(() => {
    if (!filterText.trim()) return datum
    const lowerCaseFilter = filterText.toLowerCase()
    return datum.filter(item => 
      item.title.toLowerCase().includes(lowerCaseFilter)
    )
  }, [datum, filterText])

  return (
    <div>
      <input 
        type="text" 
        placeholder="请输入食品名称" 
        onChange={handleInput} 
        value={filterText} 
      />

      {/* 渲染过滤后的结果 */}
      {filteredData.map((el) => (
        <div key={el.id} className="items">
          <img src={el.image} alt={el.title} />
          <p>{el.title}</p>
        </div>
      ))}
    </div>
  )
}

export default Filter

这里用useMemo缓存过滤结果,只有当datum或filterText变化时才重新计算,提升性能;同时用el.id作为key,比索引更符合React最佳实践。

2. 优化APICall组件的依赖数组与兜底处理

原代码的useEffect依赖数组为空,加上setDatum避免ESLint警告,同时给API返回结果加兜底,确保datum始终是数组:

import axios from "axios"
import { useState, useEffect } from 'react'

function APICall({ setDatum }) {
  const [loading, setLoading] = useState(false)

  useEffect(() => {
    const fetchAPI = async () => {
      setLoading(true)
      try {
        const res = await axios(`https://api.spoonacular.com/food/products/search?query=yogurt&apiKey=你的API密钥`)
        setDatum(res.data.products || []) // 兜底空数组,避免API返回异常导致datum为undefined
      } catch(err) {
        console.log(err)
        setDatum([]) // 错误时也设置空数组,防止后续渲染报错
      }
      setLoading(false)
    }
    fetchAPI()
  }, [setDatum]) // 添加setDatum到依赖

  if (loading) {
    return <div>加载中...</div>
  }
  return null // 加载完成后不需要显示内容,返回null即可
}

export default APICall

3. 可选:统一加载状态管理

如果想在Filter组件也显示加载提示,可以把loading状态提到App组件:

import "../App.css"
import APICall from "./APICall.js"
import Filter from "./Filter.js"
import { useState } from "react"

function App() {
  const [datum, setDatum] = useState([])
  const [loading, setLoading] = useState(false)

  return (
    <div className="App">
      {loading ? <div>加载中...</div> : <Filter datum={datum} />}
      <APICall setDatum={setDatum} setLoading={setLoading} />
    </div>
  )
}

export default App

然后修改APICall组件,接收setLoading并调用:

// APICall组件内
useEffect(() => {
  const fetchAPI = async () => {
    setLoading(true)
    try {
      // ...原API逻辑
    } catch(err) {
      // ...错误处理
    }
    setLoading(false)
  }
  fetchAPI()
}, [setDatum, setLoading])

关键总结

  • 始终确保操作的是数组本身,而非数组不存在的属性
  • 同步操作不要滥用async/await,避免把普通值当成Promise处理
  • 给状态设置合理的初始值和兜底值,防止数据未加载或加载异常时的报错
  • 用useMemo缓存计算密集的操作,提升组件性能

内容的提问来源于stack exchange,提问作者Recep Çankaya

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 12:06:30