J'essaie de configurer react-router dans un exemple d'application et j'obtiens le message d'erreur suivant:
You should not use <Link> outside a <Router>
Mon application est configurée comme suit:
const router = (
<div className="sans-serif">
<Router histpry={browserHistory}>
<Route path="/" component={Main}>
<IndexRoute component={PhotoGrid}></IndexRoute>
<Route path="/view/:postId" component={Single}></Route>
</Route>
</Router>
</div>
);
render(<Main />, document.getElementById('root'));
Main
export default () => (
<div>
<h1>
<Link to="/">Redux example</Link>
</h1>
</div>
)
Une idée de ce que je fais mal ici?
Voici un lien Sandbox pour illustrer le problème.
Je suppose que vous utilisez React-Router V4, comme vous avez utilisé la même chose dans l’original Sandbox Link.
Vous rendez le composant Main
dans l'appel à ReactDOM.render
qui restitue un composant Link
et Main est en dehors de Router
, c'est pourquoi il renvoie l'erreur:
Vous ne devez pas utiliser <Link> en dehors d’un <Routeur>
Changements:
Utilisez l’un de ces routeurs, BrowserRouter/HashRouter etc ..., car vous utilisez React-Router V4.
Le routeur ne pouvant avoir qu'un seul enfant, vous devez donc envelopper toutes les routes dans une variable div
ou Switch .
React-Router V4 n'a pas le concept de routes imbriquées, si vous souhaitez utiliser des routes imbriquées, définissez ces routes directement à l'intérieur de ce composant.
Vérifiez cet exemple de travail avec chacune de ces modifications.
const App = () => (
<BrowserRouter>
<div className="sans-serif">
<Route path="/" component={Main} />
<Route path="/view/:postId" component={Single} />
</div>
</BrowserRouter>
);
render(<App />, document.getElementById('root'));
Main
composant de la routeimport React from 'react';
import { Link } from 'react-router-dom';
export default () => (
<div>
<h1>
<Link to="/">Redux example</Link>
</h1>
</div>
)
Etc.
Vérifiez également cette réponse: Routes imbriquées avec le routeur de réaction v4
Je viens un peu avec ce code:
import React from 'react';
import { render } from 'react-dom';
// import componentns
import Main from './components/Main';
import PhotoGrid from './components/PhotoGrid';
import Single from './components/Single';
// import react router
import { Router, Route, IndexRoute, BrowserRouter, browserHistory} from 'react-router-dom'
class MainComponent extends React.Component {
render() {
return (
<div>
<BrowserRouter history={browserHistory}>
<Route path="/" component={Main} >
<IndexRoute component={PhotoGrid}></IndexRoute>
<Route path="/view/:postId" component={Single}></Route>
</Route>
</BrowserRouter>
</div>
);
}
}
render(<MainComponent />, document.getElementById('root'));
Je pense que l'erreur est due au fait que vous avez rendu le composant Main
et que le composant Main
ne connaissait rien de Router
.
Pour les utilisateurs de JEST
si vous utilisez Jest à des fins de test et que cette erreur survient, enveloppez simplement votre composant avec <BrowserRouter>
describe('Test suits for MyComponentWithLink', () => {
it('should match with snapshot', () => {
const tree = renderer
.create(
<BrowserRouter>
<MyComponentWithLink/>
</BrowserRouter>
)
.toJSON();
expect(tree).toMatchSnapshot();
});
});
Inclure le composant Link dans le composant BrowserRouter
export default () => (
<div>
<h1>
<BrowserRouter>
<Link to="/">Redux example</Link>
</BrowserRouter>
</h1>
</div>
)
Chaque fois que vous essayez d'afficher une Link
sur une page en dehors de la BrowserRouter
, vous obtiendrez cette erreur.
Ce message d'erreur indique essentiellement que tout composant qui n'est pas un enfant de notre <Router>
ne peut contenir aucun composant associé à React Router.
Vous devez migrer votre hiérarchie de composants en fonction de la façon dont vous la voyez dans la première réponse ci-dessus. Pour tous ceux qui passent en revue ce post et qui pourraient avoir besoin de regarder plus d'exemples.
Disons que vous avez un Header.js
component qui ressemble à ceci:
import React from 'react';
import { Link } from 'react-router-dom';
const Header = () => {
return (
<div className="ui secondary pointing menu">
<Link to="/" className="item">
Streamy
</Link>
<div className="right menu">
<Link to="/" className="item">
All Streams
</Link>
</div>
</div>
);
};
export default Header;
Et votre fichier App.js
ressemble à ceci:
import React from 'react';
import { BrowserRouter, Route, Link } from 'react-router-dom';
import StreamCreate from './streams/StreamCreate';
import StreamEdit from './streams/StreamEdit';
import StreamDelete from './streams/StreamDelete';
import StreamList from './streams/StreamList';
import StreamShow from './streams/StreamShow';
import Header from './Header';
const App = () => {
return (
<div className="ui container">
<Header />
<BrowserRouter>
<div>
<Route path="/" exact component={StreamList} />
<Route path="/streams/new" exact component={StreamCreate} />
<Route path="/streams/edit" exact component={StreamEdit} />
<Route path="/streams/delete" exact component={StreamDelete} />
<Route path="/streams/show" exact component={StreamShow} />
</div>
</BrowserRouter>
</div>
);
};
export default App;
Notez que le composant Header.js
utilise la balise Link
de react-router-dom
mais que le composant a été placé en dehors de <BrowserRouter>
, cela entraînera la même erreur que celle rencontrée par l'OP. Dans ce cas, vous pouvez effectuer la correction en un seul geste:
import React from 'react';
import { BrowserRouter, Route } from 'react-router-dom';
import StreamCreate from './streams/StreamCreate';
import StreamEdit from './streams/StreamEdit';
import StreamDelete from './streams/StreamDelete';
import StreamList from './streams/StreamList';
import StreamShow from './streams/StreamShow';
import Header from './Header';
const App = () => {
return (
<div className="ui container">
<BrowserRouter>
<div>
<Header />
<Route path="/" exact component={StreamList} />
<Route path="/streams/new" exact component={StreamCreate} />
<Route path="/streams/edit" exact component={StreamEdit} />
<Route path="/streams/delete" exact component={StreamDelete} />
<Route path="/streams/show" exact component={StreamShow} />
</div>
</BrowserRouter>
</div>
);
};
export default App;
Veuillez lire attentivement et vous assurer que vous avez le <Header />
ou quel que soit le composant dans lequel se trouve non seulement le <BrowserRouter>
mais également le <div>
; sinon, vous obtiendrez également le message d'erreur selon lequel un routeur ne peut avoir qu'un seul enfant faisant référence au <div>
est l'enfant de <BrowserRouter>
. Tout le reste, comme Route
et les composants, doit y être intégré dans la hiérarchie.
Alors maintenant, le <Header />
est un enfant du <BrowserRouter>
dans les balises <div>
et il peut utiliser avec succès l'élément Link
.
Write router à la place de Main in render (dernière ligne du code) . )