web-dev-qa-db-fra.com

Vous devez pas utiliser <Link> en dehors d'un <Routeur>

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:

Composant parent

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

Composant Enfant/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.

22
A7DC

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:

  1. Utilisez l’un de ces routeurs, BrowserRouter/HashRouter etc ..., car vous utilisez React-Router V4.

  2. Le routeur ne pouvant avoir qu'un seul enfant, vous devez donc envelopper toutes les routes dans une variable div ou Switch .

  3. 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.

Composant parent:

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 route

import 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

15
Mayank Shukla

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.

3
mj sameri

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();
 });
});
3
MBehtemam

Inclure le composant Link dans le composant BrowserRouter

 export default () => (
  <div>
   <h1>
      <BrowserRouter>
        <Link to="/">Redux example</Link>
      </BrowserRouter>
    </h1>
  </div>
)
1
Basavaraj Hadimani

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.jscomponent 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.

0
Daniel

Write router à la place de Main in render (dernière ligne du code) . )

0
Prakhar Mittal