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

React函数组件中useEffect调用无效的问题求助

React函数组件中useHook调用报错:Invalid hook call

问题描述

接触React时间不长,在函数组件中调用useEffect时遇到Invalid hook call报错,排查许久未解决。

Sessions组件代码

import React, { Component } from 'react';
import { useState, useEffect } from "react";

export function Sessions() {
    const [data, setData] = useState(null);
    const [loading, setLoading] = useState(true);
    const [error, setError] = useState(null);
    const [count, setCount] = useState(null);

    useEffect(() => {
        fetch(`https://localhost:7126/api/`)
            .then((response) => {
                if (!response.ok) {
                    throw new Error(
                        `This is an HTTP error: The status is ${response.status}`
                    );
                }
                return response.json();
            })
            .then((actualData) => {
                setData(actualData);
                setError(null);
                setCount(actualData.length);
            })
            .catch((err) => {
                console.log(err.message);
            });
    }, []);


    return (
        <div className="App">
            <h1>Stream Request: {count} records</h1>
            {loading && <div>A moment please...</div>}
            {error && (
                <div>{`There is a problem fetching the post data - ${error}`}</div>
            )}
            <ul>
                {data &&
                    data.map(({ StreamId, EntryTime }) => (
                        <li key={StreamId}>
                            <h3>{EntryTime}</h3>
                        </li>
                    ))}
            </ul>
        </div>
    );
}

报错信息

Warning: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:

  1. You might have mismatching versions of React and the renderer (such as React DOM)
  2. You might be breaking the Rules of Hooks
  3. You might have more than one copy of React in the same app

已排查内容

  • React和React-Dom均为最新版本;
  • 通过npm ls react验证,所有React依赖已去重,输出如下:
+-- react-dom@18.2.0
| `-- react@18.2.0 deduped
+-- react-router-dom@6.4.3
| +-- react-router@6.4.3
| | `-- react@18.2.0 deduped
| `-- react@18.2.0 deduped
+-- react@18.2.0
`-- reactstrap@9.1.5
  +-- react-popper@2.3.0
  | `-- react@18.2.0 deduped
  +-- react-transition-group@4.4.5
  | `-- react@18.2.0 deduped
  `-- react@18.2.0 deduped

路由配置代码

App.js

import "./stylesheet.css";
import React, { Component } from 'react';
import { Route, Routes } from 'react-router-dom';
import AppRoutes from './AppRoutes';
import { Layout } from './components/Layout';


export default class App extends Component {
    static displayName = App.name;

    render() {
        return (
            <Layout>
                <Routes>
                    {AppRoutes.map((route, index) => {
                        const { element, ...rest } = route;
                        return <Route key={index} {...rest} element={element} />;
                    })}
                </Routes>
            </Layout>
        );
    }
}

AppRoutes.js

import { Sessions } from "./components/Sessions";
import { Messages } from "./components/Messages";
import { Home } from "./components/Home";

const AppRoutes = [
  {
    index: true,
    element: <Home />
  },
  {
    path: '/sessions',
    element: <Sessions />
  },
  {
    path: '/messages',
    element: <Messages />
  }
];

export default AppRoutes;

解决方案

1. 修复组件内状态更新逻辑(必做)

你的useEffect未在请求完成(成功/失败)时更新loading状态,也未在错误发生时设置error状态,会导致页面一直显示加载提示且错误无法展示。修改后的useEffect:

useEffect(() => {
    fetch(`https://localhost:7126/api/`)
        .then((response) => {
            if (!response.ok) {
                throw new Error(
                    `This is an HTTP error: The status is ${response.status}`
                );
            }
            return response.json();
        })
        .then((actualData) => {
            setData(actualData);
            setError(null);
            setCount(actualData.length);
            setLoading(false); // 请求成功后关闭加载状态
        })
        .catch((err) => {
            console.log(err.message);
            setError(err.message); // 设置错误状态
            setLoading(false); // 请求失败后关闭加载状态
        });
}, []);

2. 排查Hook调用报错核心原因

你已排除版本不兼容和多份React的问题,重点检查以下几点:

  • 检查Layout组件:如果Layout是类组件,确保内部未调用Hook;如果是函数组件,确保所有Hook都在顶层调用,未违反Hook规则。
  • 修改组件导出/导入方式:尝试将Sessions改为默认导出:
    // Sessions.js
    export default function Sessions() {
        // 原有代码不变
    }
    
    然后在AppRoutes中修改导入:
    import Sessions from "./components/Sessions";
    
  • 禁用React DevTools:若DevTools版本过旧,可能与React 18不兼容,禁用后刷新页面验证报错是否消失。
  • 隔离其他组件干扰:临时注释AppRoutes中的其他路由,仅保留Sessions路由,排查是否为其他组件导致的报错。

3. 优化组件导入语句

合并重复的React导入,简化代码:

import React, { useState, useEffect } from 'react';

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 18:05:44