不变违规:您不应该在 <Router> 之外使用 <Switch>
Posted
技术标签:
【中文标题】不变违规:您不应该在 <Router> 之外使用 <Switch>【英文标题】:Invariant Violation: You should not use <Switch> outside a <Router> 【发布时间】:2018-11-08 03:01:17 【问题描述】:我有一个问题不知道如何解决,运行 npm test 时出现此错误
不变违规:您不应在
<Router>
之外使用<Switch>
问题可能是什么,我该如何解决?我跑的测试是react自带的标准app.test.js
class App extends Component
render()
return (
<div className = 'app'>
<nav>
<ul>
<li><Link exact activeClassName="current" to='/'>Home</Link></li>
<li><Link exact activeClassName="current" to='/TicTacToe'>TicTacToe</Link></li>
<li><Link exact activeClassName="current" to='/NumGame'>Quick Maths</Link></li>
<li><Link exact activeClassName="current" to='/HighScore'>Highscore</Link></li>
<li><Link exact activeClassName="current" to='/Profile'>Profile</Link></li>
<li><Link exact activeClassName="current" to='/Login'>Sign out</Link></li>
</ul>
</nav>
<Switch>
<Route exact path='/' component=Home></Route>
<Route path='/TicTacToe' component=TicTacToe></Route>
<Route path='/NumGame' component=NumberGame></Route>
<Route path='/HighScore' component=HighScore></Route>
<Route path='/Profile' component=Profile></Route>
<Route path='/Login' component=SignOut1></Route>
</Switch>
</div>
);
;
【问题讨论】:
请注意,此错误与您正在运行单元测试这一事实没有任何关系 - 您也会在运行时得到它。 【参考方案1】:错误是正确的。您需要用BrowserRouter
或HashRouter
、MemoryRouter
等其他替代方法包装Switch
。这是因为BrowserRouter
和替代方案是所有路由器组件的通用低级接口,它们使用 html 5 history
API,您需要它在路由之间来回导航。
试着这样做
import BrowserRouter, Switch, Route from 'react-router-dom';
然后像这样包装所有东西
<BrowserRouter>
<Switch>
//your routes here
</Switch>
</BrowserRouter>
【讨论】:
谢谢你解决了这个错误!但是现在我又得到了一个.. 错误:查看文件以进行更改时出错:FSEvent.FSWatcher._handle.onchange (fs.js:1360:9) npm ERR 的 _errnoException (util.js:1019:11) 处的 EMFILE!测试失败。有关详细信息,请参见上文。 @Fille_M 重启你的开发服务器 是的,试试@casraf 建议始终将 BrowserRouter 放在导航组件中,如下所示:
import React, Component from 'react'
import render from 'react-dom'
import BrowserRouter, Route, NavLink, Switch from 'react-router-dom'
var Componente1 = () => (<div>Componente 1</div>)
var Componente2 = () => (<div>Componente 2</div>)
var Componente3 = () => (<div>Componente 3</div>)
class Rotas extends Component
render()
return (
<Switch>
<Route exact path='/' component=Componente1></Route>
<Route exact path='/comp2' component=Componente2></Route>
<Route exact path='/comp3' component=Componente3></Route>
</Switch>
)
class Navegacao extends Component
render()
return (
<ul>
<li>
<NavLink to="/">Comp1</NavLink>
</li>
<li>
<NavLink exact to="/comp2">Comp2</NavLink>
</li>
<li>
<NavLink exact to="/comp3">Comp3</NavLink>
</li>
</ul>
)
class App extends Component
render()
return (
<BrowserRouter>
<div>
<Navegacao />
<Rotas />
</div>
</BrowserRouter>
)
render(<App/>, document.getElementById("root"))
注意:BrowserRouter 只接受一个子元素。
【讨论】:
BrowserRouter 实际上可以接受多个子元素。 这很冗长。我发现它很有帮助。【参考方案3】:我也面临同样的问题。当我“从 react-router-dom 导入 BrowserRouter”时解决了 并编写代码
<BrowserRouter>
<Switch>
//your routes here
</Switch>
</BrowserRouter>
【讨论】:
【参考方案4】:根据 React Router 开发人员的说法,处理此问题的正确方法是将单元测试包装在 Router 中。建议使用MemoryRouter
,以便能够在测试之间重置路由器。
您仍然可以执行以下操作:
<BrowserRouter>
<App />
</BrowserRouter>
然后在App
:
<Switch>
<Route />
<Route />
</Switch>
App
的单元测试通常类似于:
const content = render(<App />); // Fails Unit test
将单元测试更新为:
const content = render(<MemoryRouter><App /></MemoryRouter>); // Passes Unit test
【讨论】:
太好了,谢谢,MemoryRouter 正是我所缺少的!【参考方案5】:您不能将 react-router 4.3 与 react-router-dom 4.4 一起使用,反之亦然。 (编辑:这样写出来:为什么这不被认为是一个重大变化?)
确保您拥有相同的版本
【讨论】:
【参考方案6】:确保在所有嵌套组件中都有正确的导入。如果其中一个从 react-router 而不是 react-router-dom 导入 Switch,则可能会出现该错误。保持一切与 'react-router-dom' 一致(无论如何都会重新导出 react-router 组件)。检查:
"react-router": "^5.2.0",
"react-router-dom": "^5.2.0",
【讨论】:
【参考方案7】:你应该这样写你的代码
import BrowserRouter, Switch, Router from 'react-router-dom
class App extends Component
render()
return (
<div className = 'app'>
<nav>
<ul>
<li><Link exact activeClassName="current" to='/'>Home</Link></li>
<li><Link exact activeClassName="current" to='/TicTacToe'>TicTacToe</Link></li>
<li><Link exact activeClassName="current" to='/NumGame'>Quick Maths</Link></li>
<li><Link exact activeClassName="current" to='/HighScore'>Highscore</Link></li>
<li><Link exact activeClassName="current" to='/Profile'>Profile</Link></li>
<li><Link exact activeClassName="current" to='/Login'>Sign out</Link></li>
</ul>
</nav>
<BrowserRouter>
<Switch>
<Route exact path='/' component=Home></Route>
<Route path='/TicTacToe' component=TicTacToe></Route>
<Route path='/NumGame' component=NumberGame></Route>
<Route path='/HighScore' component=HighScore></Route>
<Route path='/Profile' component=Profile></Route>
<Route path='/Login' component=SignOut1></Route>
</Switch>
<BrowserRouter/>
</div>
);
;
【讨论】:
【参考方案8】:我的做法是使用yarn add react-router-dom
或npm install react-router-dom
更新依赖项并删除node_modules 文件夹并再次运行yarn
或npm install
。
【讨论】:
我在我的项目中找不到Error: Invariant failed: You should not use <Link>,<Switch>,<Route> outside a <Router>[enter image description here][1]
[Error: Invariant failed: You should not use <Link>,<Switch>,<Route> outside a <Router> ][1]
1. Open Index.js or Index.jsx
2. add-> import BrowserRouter from "react-router-dom";
3.Rap <App /> in <BrowserRouter> and </BrowserRouter>
should look like :
ReactDOM.render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>,
document.getElementById("root")
);
【讨论】:
此问题已包含多个答案和一个已接受的答案。您能否解释(通过编辑您的答案)您的答案与其他答案的不同之处?也知道从长远来看,仅代码的答案是没有用的。【参考方案10】:我找到了解决这个问题的方法
这里是示例代码
import React from 'react';
import Home from './HomeComponent/Home';
import Switch, Route from 'react-router';
import BrowserRouter from "react-router-dom";
class App extends React.Component
render()
return(
<BrowserRouter>
<Switch>
<Route path="/" render=props => (
<Home ...props/>
)/>
</Switch>
</BrowserRouter>
)
export default App;
【讨论】:
【参考方案11】:我的 NavLink 和 Route 位于不同的文件中,为了阻止此错误,我必须将它们都包装在 BrowserRouter 中:
import React from 'react';
import NavLink, BrowserRouter from 'react-router-dom'
const MainNav = () => (
<BrowserRouter>
<nav>
<ul>
<li>
<NavLink exact activeClassName='current' to='/'>Home</NavLink>
</li>
<li>
<NavLink exact activeClassName='current' to='/users'>Users</NavLink>
</li>
</ul>
</nav>
</BrowserRouter>
);
export default MainNav;
import React from 'react';
import Switch, Route from 'react-router-dom';
import Home from '../views/HomeView';
import UsersView from '../views/UsersView';
import BrowserRouter from 'react-router-dom';
const MainRoutes = () => (
<BrowserRouter>
<Switch>
<Route exact path='/' component=Home></Route>
<Route exact path='/users' component=UsersView></Route>
</Switch>
</BrowserRouter>
);
export default MainRoutes;`
【讨论】:
以上是关于不变违规:您不应该在 <Router> 之外使用 <Switch>的主要内容,如果未能解决你的问题,请参考以下文章
使用 Enzyme 测试 React 组件时出错:'不变违规:您不应在 <Router> 外使用 <Link>'
不变式失败:您不应该在 <Router> 之外使用 <Link>
错误:不变量失败:您不应该在 <Router> 之外使用 <Link> 进行反应
开玩笑 - 不变式失败:您不应该在 <Router> 之外使用 <Link>