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

React无效Hook调用问题:转函数组件仍报错,路由修改后遇新错误

React项目路由与Hook报错解决方案

问题概述

开发支持项目创建/编辑的React应用时遇到两个核心问题:

  • 初始报错:react.development.js:1476 Uncaught Error: Invalid hook call. Hooks can only be called inside of the body of a function component.,将App转为函数组件、替换Switch为Routes、component改为element后,浏览器仍无渲染内容。
  • 改用RouterProvider和createBrowserRouter后,出现新错误:Cannot read properties of undefined (reading 'map'),错误来自routes.map代码。

相关代码文件

App.js(初始报错版本)

import React from "react";
import { Routes, Route } from "react-router-dom";
import MainPage from "./MainPage";

const App = () => {
  return (
    <Routes>
      <Route path="/projects" element={<MainPage />} />
    </Routes>
  );
};

export default App;

App.js(最初版本)

import React from 'react';
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom';
import MainPage from './MainPage';
import LoginPage from './LoginPage';

const App = () => (
  <Router>
    <Switch>
      <Route path="/login" component={LoginPage} />
      <Route path="/projects" component={MainPage} />
    </Switch>
  </Router>
);

export default App;

App.js(改用RouterProvider版本)

import React from "react";
import { RouterProvider, createBrowserRouter } from "react-router-dom";
import { Routes, Route } from "react-router-dom";
import MainPage from "./MainPage";

const router = createBrowserRouter();

const routes = [
  { path: "/projects", element: <MainPage /> }
];

const App = () => {
  return (
    <RouterProvider router={router}>
      <Routes>
        {routes.map((route) => (
          <Route path={route.path} element={route.element} />
        ))}
      </Routes>
    </RouterProvider>
  );
};

export default App;

MainPage.js

import React, { useState, useEffect } from 'react';
import {
  Button, TableContainer, Table, TableHead, TableRow, TableBody, TableCell
} from 'carbon-components-react';

const MainPage = () => {
  const [projects, setProjects] = useState([]);

  useEffect(() => {
    fetch('/api/projects')
      .then((res) => res.json())
      .then((data) => setProjects(data.projects));
  }, []);

  const handleCreateProject = () => {
    const projectName = window.prompt('Enter the name of the new project:');
    if (projectName) {
      fetch('/api/projects', {
        method: 'POST',
        body: JSON.stringify({ name: projectName }),
        headers: { 'Content-Type': 'application/json' },
      })
        .then((res) => res.json())
        .then((data) => setProjects([...projects, data.project]));
    }
  };

  return (
    <div>
      <h1>My Projects</h1>
      <Button onClick={handleCreateProject}>Create New Project</Button>
      <TableContainer>
        <Table>
          <TableHead>
            <TableRow>
              <TableCell>Name</TableCell>
            </TableRow>
          </TableHead>
          <TableBody>
            {projects.map((project) => (
              <TableRow key={project.id}>
                <TableCell>{project.name}</TableCell>
              </TableRow>
            ))}
          </TableBody>
        </Table>
      </TableContainer>
    </div>
  );
};

export default MainPage;

index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

package.json依赖

"dependencies": {
    "@testing-library/jest-dom": "^5.16.5",
    "@testing-library/react": "^13.4.0",
    "@testing-library/user-event": "^13.5.0",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-scripts": "5.0.1",
    "web-vitals": "^2.1.4"

问题排查与解决方案

1. 初始Hook报错与无渲染问题

核心原因有两个:

  • 缺少react-router-dom依赖:代码中导入了路由组件,但package.json未声明该依赖,导致路由组件无法正常初始化,引发Hook调用环境异常。
  • 路由组件未在上下文提供者内:Routes必须包裹在BrowserRouter或RouterProvider中才能生效,否则无法识别路由规则。

解决步骤:

  1. 安装react-router-dom:
npm install react-router-dom@6
  1. 修正App.js(Routes版本):
import React from "react";
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import MainPage from "./MainPage";
import LoginPage from "./LoginPage";

const App = () => {
  return (
    <Router>
      <Routes>
        <Route path="/projects" element={<MainPage />} />
        <Route path="/login" element={<LoginPage />} />
        <Route path="/" element={<MainPage />} /> {/* 添加默认路由 */}
      </Routes>
    </Router>
  );
};

export default App;

2. RouterProvider版本的map报错问题

代码存在两个错误:

  • createBrowserRouter未传入路由配置数组,导致router实例无效。
  • 错误地在RouterProvider内部嵌套Routes,不符合react-router-dom v6的RouterProvider用法。

修正后的App.js(RouterProvider版本):

import React from "react";
import { RouterProvider, createBrowserRouter } from "react-router-dom";
import MainPage from "./MainPage";
import LoginPage from "./LoginPage";

// 定义路由配置
const routes = [
  { path: "/projects", element: <MainPage /> },
  { path: "/login", element: <LoginPage /> },
  { path: "/", element: <MainPage /> }
];

// 创建router实例并传入配置
const router = createBrowserRouter(routes);

const App = () => {
  return <RouterProvider router={router} />;
};

export default App;

额外防护:MainPage请求异常处理

如果后端接口未就绪,data.projects可能为undefined,引发map报错,添加兜底处理:

useEffect(() => {
  fetch('/api/projects')
    .then((res) => {
      if (!res.ok) throw new Error('请求失败');
      return res.json();
    })
    .then((data) => setProjects(data.projects || []))
    .catch((err) => {
      console.error(err);
      setProjects([]);
    });
}, []);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 08:47:19