Invariant Violation: You should not use <Switch> outside a <Router>

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>
);
}
};
103590 次浏览

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>

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.

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>

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

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

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",

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>
);
}
};

The way I did was updating the dependencies with yarn add react-router-dom or npm install react-router-domand deleting the node_modules folder and running yarn or npm install again.

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")
);

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;

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;`