【问题标题】:Invariant Violation: You should not use <Switch> outside a <Router>不变违规:您不应该在 <Router> 之外使用 <Switch>
【发布时间】:2018-11-08 03:01:17
【问题描述】:

我有一个问题不知道如何解决,运行 npm test 时出现此错误

不变违规:您不应在 &lt;Router&gt; 之外使用 &lt;Switch&gt;

问题可能是什么,我该如何解决?我跑的测试是react自带的标准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>
    );
  }
};

【问题讨论】:

  • 请注意,此错误与您正在运行单元测试这一事实没有任何关系 - 您也会在运行时得到它。

标签: javascript reactjs react-router


【解决方案1】:

错误是正确的。您需要用BrowserRouterHashRouterMemoryRouter 等其他替代方法包装Switch。这是因为BrowserRouter 和替代方案是所有路由器组件的通用低级接口,它们使用 HTML 5 history API,您需要它在路由之间来回导航。

试着这样做

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

然后像这样包装所有东西

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

【讨论】:

  • 谢谢你解决了这个错误!但是现在我又得到了一个.. 错误:查看文件以进行更改时出错:FSEvent.FSWatcher._handle.onchange (fs.js:1360:9) npm ERR 的 _errnoException (util.js:1019:11) 处的 EMFILE!测试失败。有关详细信息,请参见上文。
  • @Fille_M 重启你的开发服务器
  • 是的,试试@casraf 建议
  • 应该是
  • 对于connected-react-router它不工作:(github.com/supasate/connected-react-router
【解决方案2】:

始终将 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 只接受一个子元素。

【讨论】:

  • BrowserRouter 实际上可以接受多个子元素。
  • 这很冗长。我发现它很有帮助。
【解决方案3】:

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

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

【讨论】:

    【解决方案4】:

    根据 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
    

    【讨论】:

    • 太好了,谢谢,MemoryRouter 正是我所缺少的!
    【解决方案5】:

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

    确保您拥有相同的版本

    【讨论】:

      【解决方案6】:

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

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

      【讨论】:

        【解决方案7】:

        你应该这样写你的代码

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

        【讨论】:

          【解决方案8】:

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

          【讨论】:

          • 我在我的项目中找不到 ,可能是在没有适当身份验证的情况下调用 google apis 的原因。无论如何,您的解决方案将 react-router-dom 从 5.2.0 升级到 5.3.0 并修复了此错误,谢谢!
          【解决方案9】:
          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")
          );
          

          【讨论】:

          • 此问题已包含多个答案和一个已接受的答案。您能否解释(通过编辑您的答案)您的答案与其他答案的不同之处?也知道从长远来看,仅代码的答案是没有用的。
          【解决方案10】:

          我找到了解决这个问题的方法

          这里是示例代码

          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;
          

          【讨论】:

            【解决方案11】:

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

            【讨论】:

              猜你喜欢
              • 2019-11-27
              • 2019-09-16
              • 2020-10-23
              • 2021-08-09
              • 2020-08-04
              • 2019-08-28
              • 2020-09-19
              • 2020-09-03
              相关资源
              最近更新 更多