Invariant Violation: You should not use <Switch> outside a <Router>
JavascriptReactjsReact RouterJavascript Problem Overview
I have a problem that I don't know how to solve, I get this error when running npm test
>Invariant Violation: You should not use <Switch>
outside a <Router>
What can the problem be and how can I solve it? The test I run is the standard app.test.js that comes with react
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>
);
}
};
Javascript Solutions
Solution 1 - Javascript
The error is correct. You need to wrap the Switch
with BrowserRouter
or other alternatives like HashRouter
, MemoryRouter
. This is because BrowserRouter
and alternatives are the common low-level interface for all router components and they make use of the HTML 5 history
API, and you need this to navigate back and forth between your routes.
Try doing this rather
import { BrowserRouter, Switch, Route } from 'react-router-dom';
And then wrap everything like this
<BrowserRouter>
<Switch>
//your routes here
</Switch>
</BrowserRouter>
Solution 2 - Javascript
The proper way to handle this, according to React Router devs, is to wrap your unit test in a Router. Using MemoryRouter
is recommended in order to be able to reset the router between tests.
You can still do something like the following:
<BrowserRouter>
<App />
</BrowserRouter>
Then in App
:
<Switch>
<Route />
<Route />
</Switch>
Your unit tests for App
would normally be something like:
const content = render(<App />); // Fails Unit test
Update the unit test to:
const content = render(<MemoryRouter><App /></MemoryRouter>); // Passes Unit test
Solution 3 - Javascript
Always put BrowserRouter in the navegations components, follow the example:
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"))
Note: the BrowserRouter accept only one children element.
Solution 4 - Javascript
Make sure to have correct imports in all nested components. You might get that error if one of them imports Switch from react-router instead of react-router-dom. Keeping everything consistent with 'react-router-dom' (that reexports react-router components anyway). Checked with:
"react-router": "^5.2.0",
"react-router-dom": "^5.2.0",
Solution 5 - Javascript
The way I did was updating the dependencies with yarn add react-router-dom
or npm install react-router-dom
and deleting the node_modules folder and running yarn
or npm install
again.
Solution 6 - Javascript
I was facing the same issue. It's resolved when I "import BrowserRouter from react-router-dom" and write code
<BrowserRouter>
<Switch>
//your routes here
</Switch>
</BrowserRouter>
Solution 7 - Javascript
You can't use react-router 4.3 with react-router-dom 4.4 or vice versa. (Edit: writing it out like that: Why isn't that considered a breaking change?)
Make sure you will have same versions
Solution 8 - Javascript
You Should write your code like this
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>
);
}
};
Solution 9 - Javascript
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")
);
Solution 10 - Javascript
i found a solution to resolve this issue
here is the Example code
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;
Solution 11 - Javascript
My NavLink and Route are in separate files, in order to stop this error I had to wrap them both in 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;`