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

React报错Invalid hook call,使用useState实现搜索筛选功能如何解决?

错误原因
  • 你当前使用的是类组件(代码包含this.setState、this.state等类组件专属语法),但React Hook 仅支持在函数组件顶层或者自定义Hook内部调用,禁止在类组件的实例方法、普通JS函数、条件/循环分支中调用。你将useState('')写在类组件的getSearchData实例方法中,完全不符合Hook使用规则,直接触发Invalid hook call报错。
  • 额外逻辑问题:你将searchTerm状态定义在getSearchData方法内部,但在render的input onChange事件中直接调用setSearchTerm,该变量不在onChange的作用域范围内,即使Hook可用也会触发变量未定义错误。
解决方案

这里提供两种适配方案,可根据你的开发需求选择:

方案1:保持类组件写法,移除Hook,用类组件state管理搜索词

  1. 在类组件的state初始化逻辑中新增searchTerm字段:
constructor(props) {
  super(props);
  this.state = {
    productList: [],
    searchTerm: '' // 新增搜索词状态
    // 其他原有state字段
  }
}
  1. 修改渲染区域的input onChange事件,用类组件的setState更新搜索词:
<input 
  className="search-input" 
  placeholder="Search..." 
  type="text" 
  onChange={event => this.setState({searchTerm: event.target.value})} 
/>
  1. 改造getSearchData方法,删除Hook调用,直接从类组件state取搜索词:
getSearchData(){
  const searchTerm = this.state.searchTerm;
  return this.state.productList.filter((item)=>{
    return item.name.toLowerCase().includes(searchTerm.toLocaleLowerCase())
  }).map((item, index) => {
    return (
      <li key={index}>
        <a onClick={(e) => this._navigateShop(route.product_details + "/" + item.id)}>{item.name}</a>
      </li>
    )
  })
}

方案2:整体改为函数组件写法,符合Hook使用规则

如果你倾向于使用Hook开发,可以将整个组件重构为函数组件,示例代码如下:

import { useState, useEffect } from 'react';
// 其他依赖引入

function 你的组件名(props) {
  const [productList, setProductList] = useState([]);
  const [searchTerm, setSearchTerm] = useState('');

  // 产品数据加载逻辑
  const loadSearchData = async () => {
    const response = await getActiveProduct(null);
    if(response.code == API_SUCCESS){
      setProductList(response.data.product);
    }
  }

  // 组件挂载时加载数据
  useEffect(() => {
    loadSearchData();
  }, []);

  // 导航方法改造(不需要this绑定)
  const _navigateShop = (path) => {
    // 原有导航逻辑
  }

  // 搜索结果渲染逻辑
  const searchResult = productList.filter((item)=>{
    return item.name.toLowerCase().includes(searchTerm.toLocaleLowerCase())
  }).map((item, index) => {
    return (
      <li key={index}>
        <a onClick={(e) => _navigateShop(route.product_details + "/" + item.id)}>{item.name}</a>
      </li>
    )
  })

  // 组件渲染
  return (
    <div className="search-field collapse" id="searchToggle" >
      <input 
        className="search-input" 
        placeholder="Search..." 
        type="text" 
        onChange={event => setSearchTerm(event.target.value)} 
      />
      <a type="button" data-toggle="collapse" data-target="#searchToggle" aria-controls="searchToggle" aria-expanded="false">
        <i className="icon_close search-close"></i>
      </a>
      <div className="search-dropdown">
        {searchResult}
      </div>
    </div>
    // 其他原有组件内容
  )
}

export default 你的组件名;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 03:30:05