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

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

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.


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

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>