不变式失败:您不应在<Router>外使用<Route>

Pav*_*vel 13 reactjs react-router react-router-dom

react-router-domReact应用程序中使用路由。我的应用程序的一部分提取到另一个软件包中。依赖项列表如下所示:

./app/dashboard/package.json

{
  "dependencies": {
    "@app/components": "^1.0.0",
    "react": "^16.8.5",
    "react-dom": "^16.8.5",
    "react-router-dom": "^5.0.0"
  }
}
Run Code Online (Sandbox Code Playgroud)

./app/components/package.json

{
  "peerDependencies": {
    "react-router-dom": "^5.0.0"
  }
}
Run Code Online (Sandbox Code Playgroud)

当我使用@app/components需要组件的组件时,react-router-dom出现以下错误:

Uncaught Error: Invariant failed: You should not use <Route> outside a <Router> 
The above error occurred in the <Context.Consumer> component:
Uncaught (in promise) Error: Invariant failed: You should not use <Route> outside a <Router>
Run Code Online (Sandbox Code Playgroud)

为什么会引发此错误?在App.js我用BrowserRouter

import React, { Suspense } from 'react';
import { Switch, Route } from 'react-router-dom';
import { Placeholder } from '@app/components';

const Auth = React.lazy(() => import(/* webpackPrefetch: true */ './pages/Auth'));
const Index = React.lazy(() => import(/* webpackPrefetch: true */ './pages/Index'));

const App = () => (
  <Suspense fallback={<Placeholder />}>
    <Switch>
      <Route path="/auth" component={Auth} />
      <Route path="/" component={Index} />
    </Switch>
  </Suspense>
);

export default App;
Run Code Online (Sandbox Code Playgroud)

client.jsx

import React from 'react';
import { render } from 'react-dom';
import { BrowserRouter } from 'react-router-dom';

import App from './App';

render(
  <BrowserRouter>
    <App />
  </BrowserRouter>,
  document.getElementById('root'),
);
Run Code Online (Sandbox Code Playgroud)

小智 20

我通过更改解决了这个问题:

import {Route, Switch} from "react-router";
Run Code Online (Sandbox Code Playgroud)

import {Route, Switch} from "react-router-dom";
Run Code Online (Sandbox Code Playgroud)

只需添加-dom。


Pav*_*vel 14

2 个 React 实例的问题

  • 尝试渲染 &lt;BrowserRouter&gt; 的多个实例导致我的代码中出现此异常,感谢您的提示! (2认同)

小智 14

我在测试时遇到了这个问题,并通过用路由器包装我的测试组件来解决它。

import React from 'react';
import ReactDom from 'react-dom';
import Header from '../components/Header/Header';
import { BrowserRouter } from 'react-router-dom';

it('renders Header without crashing', () => {
  const div = document.createElement('div');

  ReactDom.render(
    <BrowserRouter>
      <Header />
    </BrowserRouter>, 
  div);

  ReactDom.unmountComponentAtNode(div);
});
Run Code Online (Sandbox Code Playgroud)

Jest, Enzyme: Invariant Violation: You should not use or ,要测试包含和 withRouter 的组件(使用 Jest),您需要在测试中导入 Router,而不是在您的组件中 import { BrowserRouter as Invariant Violation: You should not use or withRouter() 外部根据 react router 4 docs,组件被认为是有效的,我可以在其中创建由 s 组成的组件,然后将它们导入另一个组件并放置在 .

  • 您不应该使用 `&lt;MemoryRouter&gt;` 进行测试吗? (2认同)

小智 9

您应该在 Router 标签中包含 Route 标签、Link 标签。

import React, { Component } from 'react';
import { BrowserRouter as Router, Route, Link } from "react-router-dom";

const Home = () => {
  return (
    <div>
      <p>Home</p>
    </div>
  );
};

const About = () => {
  return (
    <div>
      <p>About</p>
    </div>
  );
};

const Contact = () => {
  return (
    <div>
      <p>Contact</p>
    </div>
  );
};
class App extends Component {
  render() {
    return (
        <Router>
              <div>
              <h1>W3Adda - Simple SPA</h1>
                <nav>
                  <ul>
                    <li>
                      <Link to="/">Home</Link>
                    </li>
                    <li>
                      <Link to="/about">About</Link>
                    </li>
                    <li>
                      <Link to="/contact">Users</Link>
                    </li>
                  </ul>
                </nav>

                <Route path="/" exact component={Home} />
                <Route path="/about" component={About} />
                <Route path="/contact" component={Contact} />
              </div>
        </Router>
    );
  }
}

export default App;
Run Code Online (Sandbox Code Playgroud)


Chr*_*Ngo 7

您还需要Router从中导入命名导出react-router-dom并将其包裹在您的 Switch/Route 组件周围。

const App = () => (
  <Router>
    <Suspense fallback={<Placeholder />}>
      <Switch>
        <Route path="/auth" component={Auth} />
        <Route path="/" component={Index} />
      </Switch>
    </Suspense>
  </Router>
);
Run Code Online (Sandbox Code Playgroud)


Meh*_*ani 6

我在测试链接到项目的组件(使用npm link)期间得到了这个,并且由于react-router-dom加载了不止一次,以下解决方案适用于我的情况:

在里面webpack.config.js我补充说:

resolve: {
    alias: {        
        'react-router-dom': path.resolve('./node_modules/react-router-dom')
    }
}
Run Code Online (Sandbox Code Playgroud)

  • '祝福你!!当处理具有“react-router-dom”作为依赖项的本地包时,也会发生这种情况 (2认同)

小智 6

我解决了这个问题,只是导入BrowserRouterfrom react-router-dominindex.js并添加:

<BrowserRouter>
   <App>
 </BrowserRouter>
Run Code Online (Sandbox Code Playgroud)

之内:

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
 document.getElementById('root'));
Run Code Online (Sandbox Code Playgroud)


小智 5

我对重定向组件有类似的问题。结果是我从“react-router”而不是“react-router-dom”调用了重定向。

Error: Invariant failed: You should not use <Redirect> outside a <Router>
Run Code Online (Sandbox Code Playgroud)