React+TypeScript开发Chrome扩展遇withRouter路由报错求助
withRouter 报错:You should not use <withRouter(...) /> outside a 我来帮你排查这个问题——这个报错本质是被withRouter包装的TimeEntryEditComponent在渲染时,没有处于任何Router组件的上下文范围内。结合你贴的代码,主要有两个可能的问题点,以及对应的解决办法:
1. 修复路由结构的嵌套错误
你的当前路由代码里,StoreContext.Provider直接放在了Switch组件内部,但Switch的设计是只能直接包含Route或Redirect子元素,这种嵌套方式会导致路由上下文无法正确传递给Route挂载的组件。
你需要调整上下文提供者和路由组件的嵌套顺序,确保Switch的直接子元素都是Route,同时让所有路由组件能同时拿到路由和store上下文:
方案一(推荐:Store上下文包裹整个Router)
import {MemoryRouter as Router, Route, Switch} from 'react-router-dom'; import { TimeEntryEditComponent } from './components/time-entry-edit.component'; // 将StoreContext.Provider放在Router外层,确保整个路由体系都能访问到store <StoreContext.Provider value={store}> <Router> <Switch> <Route exact path="/" component={HomePageComponent} /> <Route path="/time-entry/:id" component={TimeEntryEditComponent} /> <Route path="/issue-edit/:id" component={IssueEditComponent} /> </Switch> </Router> </StoreContext.Provider>
方案二(如果Router需要依赖Store)
如果你的MemoryRouter配置需要依赖store中的数据,可以把StoreContext.Provider放在Router内部、Switch外层:
<Router> <StoreContext.Provider value={store}> <Switch> <Route exact path="/" component={HomePageComponent} /> <Route path="/time-entry/:id" component={TimeEntryEditComponent} /> <Route path="/issue-edit/:id" component={IssueEditComponent} /> </Switch> </StoreContext.Provider> </Router>
2. 检查组件是否在Router上下文外被调用
请排查你的代码库,确认有没有其他地方直接渲染了TimeEntryEditComponent(比如Chrome扩展的popup页面、content script或者其他独立组件中),如果有这种情况,要么把那个渲染位置也包裹在MemoryRouter中,要么移除该直接调用,确保只有在路由匹配时才渲染这个组件。
额外优化建议(可选)
如果你使用的是React Router v6及以上版本,withRouter已经被官方废弃了,推荐直接使用路由hooks(比如useParams、useNavigate)来获取路由相关信息,这样就不需要用withRouter包装组件,从根源上避免这类上下文问题:
// 在TimeEntryEditComponent中直接使用hooks import { useParams } from 'react-router-dom'; const TimeEntryEditComponent = () => { // 获取路由参数id const { id } = useParams<{ id: string }>(); // 你的组件逻辑... }; // 直接导出组件,不需要withRouter包装 export { TimeEntryEditComponent };
内容的提问来源于stack exchange,提问作者Aliaksandr Kirylau

