不变式失败:您不应在<router>外使用<route>

时间:2019-04-06 18:23:13

标签: reactjs react-router react-router-dom

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

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'),
);

23 个答案:

答案 0 :(得分:12)

我通过以下方法解决了这个问题:

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

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

只需添加-dom。

答案 1 :(得分:2)

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

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

笑话,酵素:不断违反:您不应使用或来 测试包含并使用Router的组件(使用Jest) 需要在测试中导入路由器,而不是在组件中导入{ BrowserRouter作为不变违规:您不应使用或 根据路由器4的响应文档, 组件被认为是有效的,我可以在其中创建组件 由组成,然后将它们导入到另一个组件中 放在。

https://xspdf.com/resolution/50584641.html

答案 2 :(得分:2)

实际上,问题出在进行路由的根组件中,不应在组件中的OUTPUT : {'key': ['AGATC', 'AATG', 'TATC']} {'key': ['2', '8', '3']} {'key': ['4', '1', '5']} {'key': ['3', '2', '5']} 标记之外添加任何组件,该组件仅期望由Router包装的单个/多个组件在该组件的Route下。

错误的代码(但是它将运行,但是您正在创建错误)-

Router

我只删除了function App() { return ( <div className="App"> <Header/> <Router> <Switch> <Route path="/" exact> <Home /> </Route> </Switch> </Router> </div> ); } ,它解决了问题。

编写代码-

<Header/>

答案 3 :(得分:1)

我在使用 CRA 和组件库创建的主应用程序中遇到了类似的情况。我们有两个独立工作的 react-router-dom 实例。库中的组件使用 <Link>,而父应用程序使用 <Router>

受到@Pavel 回答的启发,我发现可以通过添加别名来解决这个问题。如果您使用的是 webpack,您可以更改它解析 react-router-dom 模块的方式。您可以覆盖 webpack 查找依赖项的默认顺序,并使您的父应用程序 node_modules 比组件节点模块解析顺序更优先:

别名.js

const fs = require('fs');
const path = require('path');

const directory = fs.realpathSync(process.cwd());
const resolveApp = (relativePath) => path.resolve(directory, relativePath);

module.exports = {
  react: resolveApp('node_modules/react'),
  'react-router-dom': resolveApp('node_modules/react-router-dom'),
};

由 config-override.js 用来覆盖默认 CRA 设置:

const { addWebpackAlias, override, removeModuleScopePlugin } = require('customize-cra');
const aliases = require('./aliases');

module.exports = override(removeModuleScopePlugin(), addWebpackAlias(aliases));

或 webpack.config.js(如果不是 CRA):

resolve: {
  alias: {
    "react-router-dom": path.resolve(appFolder, "node_modules", "react-router-dom"),
 }
}

答案 4 :(得分:1)

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

  
Error: Invariant failed: You should not use <Redirect> outside a <Router>

答案 5 :(得分:1)

我通过将父组件包装在Router中来解决此错误。

解决错误之前

<Header />
<div className="col-md-12 pd-0-0">
  <div className="row">
    <Sidebar />
    <div className="col-sm-10 col-md-10 pd-0-0" style={style}>
      <Router>
        <Switch>
          <Route path="/dashboard/check-in" component={CheckIn} />
          <Route path="/dashboard/deals" component={Deals} />
          <Route path="/dashboard/events" component={Events} />
          <Route path="/dashboard/invoice" component={Invoice} />
          <Route path="/dashboard/notification" component={Notification} />
          <Route path="/dashboard/profile" component={Profile} />
          <Route path="/dashboard/redemption" component={Redemptions} />
          <Route path="/dashboard/restriction-management" component={RestrictionManagement} />
        </Switch>
      </Router>
    </div>
  </div>
</div>

解决错误后

<Router>
  <Header />
  <div className="col-md-12 pd-0-0">
    <div className="row">
      <Sidebar />
      <div className="col-sm-10 col-md-10 pd-0-0" style={style}>
        <Switch>
          <Route path="/dashboard/check-in" component={CheckIn} />
          <Route path="/dashboard/deals" component={Deals} />
          <Route path="/dashboard/events" component={Events} />
          <Route path="/dashboard/invoice" component={Invoice} />
          <Route path="/dashboard/notification" component={Notification} />
          <Route path="/dashboard/profile" component={Profile} />
          <Route path="/dashboard/redemption" component={Redemptions} />
          <Route path="/dashboard/restriction-management" component={RestrictionManagement} />
        </Switch>
      </div>
    </div>
  </div>
</Router>

答案 6 :(得分:0)

我修复了仅从index.js(在create-react-app上)的“ react-router-dom”中导入“ BrowserRouter”的问题,然后可以使用:

    <BrowserRouter>
       <App>
     </BrowserRouter>

替换位置:

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

答案 7 :(得分:0)

最简单的答案就在 reactstrap for Navbar 的官方文档中,请参阅此网站 https://reactstrap.github.io/components/navbar/

他们指导我们需要使用这个导入

import {NavLink} from 'reactstrap';

答案 8 :(得分:0)

如果您使用 GatsbyJS 并收到此错误,只需更改您的

import { Link } from "react-router-dom";

import { Link } from 'gatsby';

答案 9 :(得分:0)

当尝试在Solidus应用中替换Rails视图时,我遇到了类似的问题。

对我来说,解决方案是编辑视图以使用我刚刚添加但显然尚未完全配置的React Router。

例如,我从以下位置编辑了views/spree/home/index.html

<%= javascript_pack_tag 'application' %>
<%= react_component("Home/Index") %>

收件人:

<%= javascript_pack_tag 'application' %>
<%= react_component("Routes") %>

更多参考,这是我的javascript/components/Route.js

import React from "react";
import { BrowserRouter as Router, Route } from "react-router-dom";
import Home from "./Home/Index";
import Product from "./Products/Show";

class Routes extends React.Component {
  render() {
    return (
      <Router>
        <Route exact path="/" component={Home} />
        <Route path="/products/:slug" component={Product} />
      </Router>
    );
  };
};

export default Routes;

答案 10 :(得分:0)

我已经通过导入解决了这个问题

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

并将所有Route组件包装在Router组件下

 <Router>
     <Route exact path='/' component={HomePage} />
 </Router>

答案 11 :(得分:0)

在组件外部使用路由器。将所有组件包装在路由器内,然后可以在组件中使用 Link

从“ react-router-dom”导入{BrowserRouter作为路由器,路由,交换机};

<Router>
        <Appbar />
        <Switch>
          <Route exact path="/" component={Home} />
          <Route path="/mac" exact component={Mac} />
        </Switch>
       <Footer />
      </Router>

答案 12 :(得分:0)

我设法通过从<BrowserRouter>中删除router.js并将其包含在app.js中来解决了这个问题

export default function  Routes() {
  return (
     
      <Switch>
        <Route path="/" exact component={Home} />
        <Route path="/book" component={Book} />
        <Route path="/client" component={Client} />
        <Route path="/rent" component={Rent} />
        <Route path="/dash" component={Dash} />
      </Switch>
    
  );
}
function App() {
  return (
    <div>
  
  <BrowserRouter>
    <Header></Header>
    
    <Routes/>
    </BrowserRouter>
    </div>
  );
}

答案 13 :(得分:0)

在未导入的组件中使用i: 40 zeile: <g i: 41 zeile: id="4B4363F3"> i: 42 zeile: <rect i: 43 zeile: style="fill:#F6F8FF;stroke-linejoin:round;stroke-width:3.82" i: 44 zeile: id="2B4363F3" i: 45 zeile: x="228.070006" i: 46 zeile: y="714.069998" i: 47 zeile: width="2.16" i: 48 zeile: height="2.16"/> i: 49 zeile: <circle i: 50 zeile: style="fill:#F6F8FF;stroke-linecap:butt;stroke-width:0.25" i: 51 zeile: id="3B4363F3" i: 52 zeile: cx="229.150231" i: 53 zeile: cy="715.150223" i: 54 zeile: r="1.018225"/> i: 55 zeile: </g> 标签可能会导致此错误,请尝试从<Link>导入BrowserRouter

'react-router-dom'

然后确保将链接的标签包装在标签中

答案 14 :(得分:0)

您还需要从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>
);

答案 15 :(得分:0)

运行测试时,我的Create React App遇到了同样的问题,我通过将<Router></Router放在App.js内而不是像往常一样放在Index.js中来解决了这个问题。

之前:

Index.js

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

App.js

return (
    <div className="App">
        <Header />
        <Route path="/blabla" component={Whatever}
    </div>
)

之后:

Index.js:

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

App.js:

return (
    <div className="App">
        <Router>
            <Header />
            <Route path="/blabla" component={Whatever}
        </Router>
    </div>
)

答案 16 :(得分:0)

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

答案 17 :(得分:0)

在我的情况下,此错误是由于混淆了react-router和react-router-dom中的事物(withRouter,MemoryRouter)而导致的。通过仅使用react-router-dom中的内容,不变错误消失了。希望这对任何人都有帮助。

答案 18 :(得分:0)

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

我在webpack.config.js里面添加了

resolve: {
    alias: {        
        'react-router-dom': path.resolve('./node_modules/react-router-dom')
    }
}

答案 19 :(得分:0)

我通过从MyComponent删除'react-router-dom'的依赖关系解决了这个神秘的错误。我删除了'node_modules / react-router-dom'和'package.json' 我的应用程序的结构如下:

    AppFolder
    ├── README.md
    ├── build
    ├── node_modules
    │   ├── react-router-dom
    ├── package-lock.json
    ├── package.json
    ├── public
    │   ├── favicon.ico
    │   ├── index.html
    │   └── manifest.json
    └── src
        ├── App.css
        ├── App.js
        ├── App.test.js
        ├── index.js
        ├── redux
        │   ├── reducers.js
        │   └── store.js
        └── serviceWorker.js


    MyComponent
    ├── README.md
    ├── dist
    ├── node_modules
    │   ├── react-router-dom
    ├── package-lock.json
    ├── package.json
    ├── rollup.config.js
    └── src
        ├── index.js
        ├── styles.css
        └── test.js

这是App.js的源代码

import MyComponent from 'MyComponent'

export default App(){
 return (
 <div className="App">
    <HashRouter>
      <div>
        <header className="App-header">

        </header>
        <Route path="/home" component={MyComponent}/>
      </div>
    </HashRouter>
  </div>)
}

这是MyComponent的导出

export default withRouter(MyComponent);

如果在组件文件夹中保留了“ react-router-dom”,则会出现错误。

答案 20 :(得分:0)

有两个React实例的麻烦

答案 21 :(得分:0)

document.getElementById('root')之后,呈现调用的结尾处有一个悬挂的逗号。

render(
  <BrowserRouter>
    <App />
  </BrowserRouter>,
  document.getElementById('root'),
);

答案 22 :(得分:-1)

只需在“ react-router-dom”上更改“ react-router”

import {Route} from "react-router";

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