不变违规:您不应在<router>之外使用<switch>

时间:2018-05-29 12:38:50

标签: javascript reactjs react-router

我有一个问题,我不知道如何解决,运行npm test Invariant Violation: You should not use <Switch> outside a <Router>时出现此错误。问题是什么,我该如何解决?我运行的测试是带有反应的标准app.test.js

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

11 个答案:

答案 0 :(得分:37)

错误是正确的。您需要将SwitchBrowserRouterHashRouterMemoryRouter等其他替代方案一起打包。这是因为BrowserRouter和替代品是所有路由器组件的常见低级接口,并且它们使用HTML 5 history API,您需要在您的路由之间来回导航。 / p>

尝试这样做

import { BrowserRouter, Switch, Route } from 'react-router-dom';

然后包装这样的一切

<BrowserRouter>
 <Switch>
  //your routes here
 </Switch>
</BrowserRouter>

答案 1 :(得分:6)

根据React Router开发人员的说法,处理此问题的正确方法是将单元测试包装在Router中。建议使用MemoryRouter,以便能够在两次测试之间重置路由器。

您仍然可以执行以下操作:

<BrowserRouter>
  <App />
</BrowserRouter>

然后在App中输入

<Switch>
  <Route />
  <Route />
</Switch>

您对App的单元测试通常类似于:

const content = render(<App />); // Fails Unit test

将单元测试更新为:

const content = render(<MemoryRouter><App /></MemoryRouter>); // Passes Unit test

答案 2 :(得分:2)

确保所有嵌套组件中的导入均正确。如果其中一个从react-router而不是react-router-dom导入Switch,则可能会出现该错误。保持一切与“ react-router-dom”(无论如何都重新导出react-router组件)一致。已检查:

"react-router": "^5.2.0",
"react-router-dom": "^5.2.0",

答案 3 :(得分:1)

我面临着同样的问题。当我“从react-router-dom导入BrowserRouter”时,此问题已解决 并编写代码

<BrowserRouter>
 <Switch>
  //your routes here
 </Switch>
</BrowserRouter>

答案 4 :(得分:0)

始终将BrowserRouter置于导航组件中,请遵循以下示例:

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

注意:BrowserRouter仅接受一个子元素。

答案 5 :(得分:0)

您不能将react-router 4.3与react-router-dom 4.4一起使用,反之亦然。 (编辑:这样写出来:为什么那不算是重大改变?)

确保您具有相同的版本

答案 6 :(得分:0)

您应该这样编写代码

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

答案 7 :(得分:0)

我做的方法是使用yarn add react-router-domnpm install react-router-dom更新依赖关系,并删除node_modules文件夹并再次运行yarnnpm install

答案 8 :(得分:0)

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

答案 9 :(得分:0)

我找到了解决此问题的方法

这是示例代码

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;

答案 10 :(得分:0)

我的 NavLink 和 Route 位于单独的文件中,为了阻止此错误,我必须将它们都包装在 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;`