J'utilise react-router-dom
pour le routage dans mon application React
. Une partie de mon application extraite dans un autre package. La liste des dépendances ressemble à ceci:
./ 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"
}
}
Lorsque j'utilise des composants de @app/components
qui nécessitent des composants de react-router-dom
J'obtiens ces erreurs:
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>
Pourquoi jette cette erreur? Dans App.js
J'utilise 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'),
);
Problème avec 2 instances de React
Je l'ai obtenu lors du test de mon composant lié au projet (en utilisant npm link
) Et à cause de ça react-router-dom
chargé plus d'une fois, la solution suivante fonctionne dans mon cas:
À l'intérieur webpack.config.js
J'ai ajouté:
resolve: {
alias: {
'react-router-dom': path.resolve('./node_modules/react-router-dom')
}
}
Vous devez également importer l'export nommé Router
depuis react-router-dom
et l'enrouler autour de vos composants Switch/Route.
const App = () => (
<Router>
<Suspense fallback={<Placeholder />}>
<Switch>
<Route path="/auth" component={Auth} />
<Route path="/" component={Index} />
</Switch>
</Suspense>
</Router>
);
J'ai résolu cette erreur cryptique en supprimant la dépendance de 'react-router-dom' de MyComponent. J'ai supprimé 'node_modules/react-router-dom' et de 'package.json' Mon application est structurée comme suit:
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
Ceci est le code source d'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>)
}
Ceci est l'exportation pour MyComponent
export default withRouter(MyComponent);
Si "react-router-dom" est laissé dans le dossier des composants, l'erreur apparaît.
J'ai eu un problème similaire avec le composant de redirection. Il s'est avéré que j'ai appelé Rediriger depuis 'react-router' au lieu de 'react-router-dom'.
Error: Invariant failed: You should not use <Redirect> outside a <Router>
Vous devez inclure la balise Route, la balise Link à l'intérieur de la balise 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;
J'ai résolu ce problème en modifiant:
import {Route, Switch} from "react-router";
à
import {Route, Switch} from "react-router-dom";
ajoutez simplement -dom.
Je résous cette erreur, en enveloppant mon composant parent dans le routeur.
Avant de résoudre l'erreur
<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>
Après avoir résolu l'erreur
<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>
Dans mon cas, cette erreur est due à un mélange de l'utilisation des choses (withRouter, MemoryRouter) de react-router et react-router-dom. En utilisant uniquement les éléments de react-router-dom, l'erreur invariante a disparu. J'espère que cela aide n'importe qui.
J'ai eu le même problème avec mon application Create React lors de l'exécution des tests et je l'ai résolu en plaçant <Router></Router
à l'intérieur App.js
au lieu de dans Index.js
comme je l'ai toujours fait.
Avant:
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>
)
Après:
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>
)