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>
);
}
};
To fix the 'You should not use Route or withRouter() outside a Router' error with React Router v4, we should wrap our app with the BrowserRouter component. import { BrowserRouter } from "react-router-dom"; ReactDOM. render( <BrowserRouter> <App /> </BrowserRouter>, document. getElementById("root") );
Memory Router: Memory router keeps the URL changes in memory not in the user browsers. It keeps the history of the URL in memory (does not read or write to the address bar so the user can not use the browser's back button as well as the forward button. It doesn't change the URL in your browser.
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>
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With