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

IT技术 reactjs react-router react-router-dom
2021-04-07 05:26:08

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

./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"
  }
}

./app/components/package.json

{
  "peerDependencies": {
    "react-router-dom": "^5.0.0"
  }
}

当我使用@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>

为什么会抛出这个错误?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;

客户端.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'),
);
6个回答

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

import {Route, Switch} from "react-router";

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

只需添加-dom。

我在从“react-router”导入重定向时遇到了同样的问题
2021-06-14 05:26:08

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

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

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 组成的组件,然后将它们导入另一个组件并放置在 .

你不应该<MemoryRouter>用于测试吗?
2021-05-23 05:26:08
谢谢。这正是我测试所需要的。
2021-05-28 05:26:08

2 个 React 实例的问题

尝试渲染 <BrowserRouter> 的多个实例在我的代码中导致此异常,感谢您的提示!
2021-06-03 05:26:08
@SawanPatodia 我不得不重绘根组件。在整个项目中的单个 <BrowserRouter> 中必须有一个 <Router> 。
2021-06-05 05:26:08
@rodurico 我面临同样的问题。你是怎么解决的?
2021-06-12 05:26:08

您应该在 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;

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

<BrowserRouter>
   <App>
 </BrowserRouter>

在里面:

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
 document.getElementById('root'));