React类组件转换为Hooks时出现TypeError报错的求助
问题排查与修复
TypeError: Object(...) is not a function 根因说明
这个报错的本质是组件初始化时,调用的useState不是可执行的函数对象。报错行号指向function EventsSection()只是因为组件一被调用就会执行内部的Hook逻辑,并非组件定义本身有问题。
- 最常见触发原因:项目使用的React版本低于16.8。Hooks是React 16.8正式推出的能力,老版本React导出的
useState为undefined,调用时就会触发该错误。可以执行npm ls react react-dom查看版本,版本过低时升级到16.8及以上版本即可。 - 次常见原因:导入配置异常。比如React的路径别名配置错误、第三方打包工具(如Vite、Webpack)的React解析规则配置错误,可以临时在组件内打印
console.log(useState),确认是否为有效函数。
代码逻辑转写的错位问题(解决上述报错后仍会触发运行时错误)
原类组件把eventsData定义为组件外部的全局常量,作为全量数据的参考副本,你转写时删掉了这个全局常量,直接把数据塞到useState的初始值里,导致三个核心逻辑错误:
- 重置逻辑完全失效:原类组件中
selected === 3时,会把状态重置为全局的全量eventsData,你写的setEventsData()(无传参)会把状态设为undefined,后续EventsTable接收的数组类型参数异常,调用数组方法直接抛错。 - 状态类型不匹配:你写的
setEventsData({})会把原本为数组的eventsData替换为对象,后续handleSearch里调用filter方法时会直接报错。 - 搜索逻辑偏差:原类组件的搜索是基于全局全量数据过滤,而非当前已过滤的状态数据,你写的
eventsData.filter是基于当前状态过滤,会导致多次搜索时结果异常。
修复后的完整可运行代码
import React, { useState } from "react"; import styles from "./style.module.css"; import { EventsTable } from "../EventsTable"; import { TitleSearch } from "../TitleSearch"; // 保留全量原始数据常量,作为重置、搜索的基准数据源 const initialEventsData = [ { key: 1, title: "Bulletproof EP1", fileType: "Atmos", process: "match media", performedBy: "Denise Etridge", operationNote: "-", updatedAt: "26/09/2018 17:21", status: "complete", }, { key: 2, title: "Dexter EP2", fileType: "Video", process: "Compliance", performedBy: "Dane Gill", operationNote: "passed", updatedAt: "21/09/2018 12:21", status: "inProgress", }, ]; function EventsSection() { const [eventsData, setEventsData] = useState(initialEventsData); const handleFilter = (key) => { const selected = parseInt(key); if (selected === 3) { // 重置为全量原始数据,必须传数组类型 return setEventsData(initialEventsData); } // 原类组件this.setState({})为浅合并,传空对象无状态变更,Hooks中直接空操作即可 }; const handleSearch = (searchText) => { const lowerSearchText = searchText.toLowerCase(); // 基于全量原始数据过滤,和原类组件逻辑对齐 const filteredEvents = initialEventsData.filter(({ title }) => title.toLowerCase().includes(lowerSearchText) ); setEventsData(filteredEvents); }; return ( <section> <header> <h1>Events</h1> <TitleSearch onSearch={handleSearch} className={styles.action} /> </header> <EventsTable eventsData={eventsData} /> </section> ); } export { EventsSection };
内容的提问来源于stack exchange,提问作者waleedd32
相关产品推荐
相关产品推荐

