React
アプリケーションでのルーティングにreact-router-dom
を使用しています。アプリの一部が別のパッケージで抽出されました。依存関係のリストは次のようになります。
./ 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'),
);
Reactの2つのインスタンスに関する問題
名前付きエクスポートRouter
をreact-router-dom
からインポートし、スイッチ/ルートコンポーネントで囲む必要があります。
const App = () => (
<Router>
<Suspense fallback={<Placeholder />}>
<Switch>
<Route path="/auth" component={Auth} />
<Route path="/" component={Index} />
</Switch>
</Suspense>
</Router>
);
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」がコンポーネントフォルダーに残っている場合、エラーが表示されます。
Redirectコンポーネントにも同様の問題がありました。 「react-router-dom」ではなく「react-router」からリダイレクトを呼び出したことがわかりました。
Error: Invariant failed: You should not use <Redirect> outside a <Router>
ルータータグ内にルートタグ、リンクタグを含める必要があります。
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;
私はこの問題を変更して解決しました:
import {Route, Switch} from "react-router";
に
import {Route, Switch} from "react-router-dom";
-domを追加するだけです。
このエラーを解決するには、親コンポーネントをルーター内にラップします。
エラーを解決する前に
<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>
私の場合、このエラーは、react-routerとreact-router-domからのもの(withRouter、MemoryRouter)の使用を混同したことが原因で発生しました。 react-router-domからのもののみを使用することにより、不変のエラーがなくなりました。これが誰にも役立つことを願っています。
テストの実行時に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>
)