React中Invalid Hook Call Error:如何在类组件中使用useState?
在React类组件中替代Hook实现状态管理与副作用处理
你遇到的Invalid Hook Call Error是因为Hook(useState/useEffect/useParams等)只能在函数组件或自定义Hook的顶层调用,不能在类组件的render方法或其他类方法里使用。下面是针对你的需求修改后的类组件实现:
修正后的完整代码
import axios from 'axios'; import React from 'react'; class Portfolio extends React.Component { // 1. 初始化类组件状态,替代多个useState constructor(props) { super(props); this.state = { skill: [], career: [], education: [], project: [], etcEducation: [], language: [], certificate: [], award: [], introduce: [], userInfo: [] }; } // 2. 封装用户信息请求方法 getUserInfo = () => { const getToken = localStorage.getItem('token'); const getUserIdx = localStorage.getItem('userIdx'); axios.get(`http://localhost:3001/users/${getUserIdx}`, { headers: { authorization: getToken, }, }).then((res) => { const userData = res.data.data; // 使用this.setState更新状态 this.setState({ userInfo: userData }); }).catch((err) => console.log(err)); }; // 3. 封装作品集请求方法 getPortfolio = () => { const { portfolio_idx } = this.props.match.params; // 类组件中获取路由参数 axios .get(`http://localhost:3001/portfolios/${portfolio_idx}`) .then((res) => { const datas = res.data.data; // 批量更新多个状态 this.setState({ skill: datas.skill, career: datas.career, education: datas.education, project: datas.website, language: datas.language, certificate: datas.certificate, etcEducation: datas.etc_education, award: datas.award, introduce: datas.introduce }); }).catch((err) => console.log(err, '실패')); }; // 4. 使用componentDidMount替代useEffect([]),组件挂载时执行初始化请求 componentDidMount() { this.getUserInfo(); this.getPortfolio(); } render() { // 从state中解构需要使用的数据 const { skill, career, education, project, etcEducation, language, certificate, award, introduce, userInfo } = this.state; // 这里写你的JSX渲染逻辑,示例返回null,实际替换成你的UI return null; } } export default Portfolio;
关键修改点说明
- 状态管理:用类的
this.state统一管理所有状态,替换useState;更新状态时调用this.setState()(支持批量更新多个状态字段)。 - 路由参数获取:类组件中通过
this.props.match.params获取路由参数,替代useParams(如果使用React Router v6,需要用withRouter高阶组件包裹类组件才能拿到match属性)。 - 副作用处理:用
componentDidMount生命周期方法替代useEffect(() => {}, []),在组件首次挂载时执行初始化数据请求。 - 方法绑定:使用箭头函数定义类方法(
getUserInfo = () => {}),避免this指向问题,无需额外在constructor中绑定。
如果你的项目使用React Router v6,需要额外导入withRouter并包裹组件:
import { withRouter } from 'react-router-dom'; // 导出时用withRouter包裹 export default withRouter(Portfolio);
内容的提问来源于stack exchange,提问作者박세령
相关产品推荐
相关产品推荐

