React Router:在index.tsx中使用useState触发无效Hook调用错误
解决React Hooks "Invalid hook call" 错误
错误原因
你直接在全局作用域调用了useState,而React Hooks的规则明确要求:Hooks只能在函数组件的顶层作用域内调用,不能在全局、普通函数或组件外部使用。
修复方案
创建一个自定义函数组件(比如App),把状态和路由逻辑都放在这个组件内部,修改后的代码如下:
import * as React from 'react'; import * as ReactDOM from 'react-dom/client'; import { StyledEngineProvider } from '@mui/material/styles'; import Demo from './Demo'; import Home from './pages/Home'; import About from './pages/About'; import Products from './pages/Products'; import Error from './pages/Error'; import SharedLayout from './pages/SharedLayout'; import SingleProduct from './pages/SingleProduct'; import Dashboard from './pages/Dashboard'; import Login from './pages/Login'; import { BrowserRouter, Routes, Route } from 'react-router-dom'; import { useState } from 'react'; // 自定义App函数组件,所有状态和路由逻辑都在这里 function App() { // 现在useState在函数组件内部,符合规则 const [user, setUser] = useState(null); return ( <BrowserRouter> <Routes> <Route path="/" element={<SharedLayout />}> <Route index element={<Home />} /> <Route path="about" element={<About />} /> <Route path="products" element={<Products />} /> <Route path="products/:productId" element={<SingleProduct />} /> <Route path="login" element={<Login setUser={setUser} />} /> {/* 移除重复的login路由,避免路由冲突 */} <Route path="*" element={<Error />} /> </Route> </Routes> <StyledEngineProvider injectFirst> <Demo /> </StyledEngineProvider> </BrowserRouter> ); } ReactDOM.createRoot(document.querySelector('#root')!).render( <React.StrictMode> <App /> {/* 渲染自定义的App组件 */} </React.StrictMode> );
关键注意点
- 所有Hooks必须放在函数组件的顶层,不能嵌套在条件判断、循环或嵌套函数里。
- 移除了重复的
login路由,避免出现路由匹配冲突的问题。 - 把状态和路由逻辑封装在组件内,更符合React组件化的开发模式,后续扩展也更方便。
内容的提问来源于stack exchange,提问作者Ram01
相关产品推荐
相关产品推荐

