Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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>
    );
  }
};
like image 215
Fille_M Avatar asked May 29 '18 12:05

Fille_M


People also ask

Should not Use route or withRouter () outside a router?

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

What is memory router react?

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.


2 Answers

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>
like image 146
Siya Mzam Avatar answered Oct 17 '22 21:10

Siya Mzam


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
like image 15
nathanpdaniel Avatar answered Oct 17 '22 22:10

nathanpdaniel