Javascript Invariant Violation:你不应该在 <Router> 之外使用 <Switch>

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/50584641/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 04:38:45  来源:igfitidea点击:

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

javascriptreactjsreact-router

提问by Fille_M

I have a problem that I don't know how to solve, I get this error when running npm test

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

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

不变违规:您不应该<Switch>在外部使用<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

问题是什么,我该如何解决?我运行的测试是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>
    );
  }
};

回答by Siya

The error is correct. You need to wrap the Switchwith BrowserRouteror other alternatives like HashRouter, MemoryRouter. This is because BrowserRouterand alternatives are the common low-level interface for all router components and they make use of the HTML 5 historyAPI, and you need this to navigate back and forth between your routes.

错误是正确的。您需要将SwitchwithBrowserRouter或其他替代品(如HashRouter, )包裹起来MemoryRouter。这是因为BrowserRouter和替代品是所有路由器组件的通用低级接口,它们使用 HTML 5 historyAPI,您需要它来在您的路由之间来回导航。

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>

回答by Fábio Rodrigues Fonseca

Always put BrowserRouter in the navegations components, follow the example:

始终将 BrowserRouter 放在 navegations 组件中,请遵循示例:

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.

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

回答by nathanpdaniel

The proper way to handle this, according to React Router devs, is to wrap your unit test in a Router. Using MemoryRouteris recommended in order to be able to reset the router between tests.

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

You can still do something like the following:

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

<BrowserRouter>
  <App />
</BrowserRouter>

Then in App:

然后在App

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

Your unit tests for Appwould normally be something like:

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

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

Update the unit test to:

将单元测试更新为:

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

回答by Vishnu KG Cherupuzha

I was facing the same issue. It's resolved when I "import BrowserRouter from react-router-dom" and write code

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

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

回答by atom217

You can't use react-router 4.3 with react-router-dom 4.4 or vice versa. (Edit: writing it out like that: Why isn't that considered a breaking change?)

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

Make sure you will have same versions

确保您将拥有相同的版本