122 votes

Vous ne devriez pas utiliser <Link> en dehors d'un <Router>

Je suis en train de configurer réagir-routeur dans un exemple d'application, et j'obtiens l'erreur suivante:

You should not use <Link> outside a <Router>

Mon application est configuré 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'));

Enfant/Main de la composante

export default () => (
  <div>
    <h1>
      <Link to="/">Redux example</Link>
    </h1>
  </div>
)

Toute idée de ce que je fais mal ici?

Voici un bac à sable lien pour illustrer le problème.

147voto

MBehtemam Points 2700

Pour les utilisateurs de JEST

si vous utilisez Jest à des fins de test et que cette erreur se produit, 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();
 });
});
 

72voto

Mayank Shukla Points 39317

Je suis en supposant que vous utilisez Réagir-Routeur V4, que vous avez utilisé la même dans l'original Sandbox Lien.

Vous êtes rendu à l' Main de la composante dans l'appel d' ReactDOM.render qui rend un Link et de la composante Principale est à l'extérieur de l' Router, c'est pourquoi il est en train de jeter de l'erreur:

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

Changements:

  1. Utilisez l'une de ces Routeurs, BrowserRouter/HashRouter etc..., parce que vous êtes à l'aide de Réagir-Routeur V4.

  2. Routeur peut avoir qu'un seul enfant, de sorte que l'emballage de tous les itinéraires en div ou Commutateur.

  3. Réagir-Routeur V4, n'ont pas la notion d'imbrication des routes, si on veut utiliser imbriqués les itinéraires ensuite définir les itinéraires directement à l'intérieur de ce composant.


Vérifiez cet exemple de travail avec chacun de ces changements.

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 de la composante 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: Imbriquées les routes avec réagissent routeur v4

22voto

Inclure le composant Link dans le composant BrowserRouter

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

17voto

Daniel Points 1346

Chaque fois que vous essayez d'afficher un Link sur une page, c'est à l'extérieur de l' BrowserRouter , vous obtiendrez cette erreur.

Ce message d'erreur est essentiellement dire que tout élément qui n'est pas un enfant de notre - <Router> ne peut pas contenir de Réagir Routeur composants connexes.

Vous devez migrer votre hiérarchie des composants de comment vous le voyez dans la première réponse ci-dessus. Pour quelqu'un d'autre l'examen de ce post, qui peuvent avoir besoin de regarder plus d'exemples.

Disons que vous avez un Header.jscomposant 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 App.js le fichier 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 l' Header.js de la composante est prise de l'utilisation de l' Link balise à partir de la react-router-dom mais le componet a été placé à l'extérieur de l' <BrowserRouter>, cela conduira à la même erreur que celle de l'expérience par les OP. Dans ce cas, vous pouvez faire la correction dans un seul mouvement:

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 l' <Header /> ou quel que soit votre volet peut être à l'intérieur, non seulement de l' <BrowserRouter> mais aussi à l'intérieur de l' <div>, sinon vous aurez aussi l'erreur qu'un Routeur ne peut avoir qu'un enfant et qui se réfère à l' <div> qui est l'enfant de l' <BrowserRouter>. Tout le reste comme Route et les composants doivent aller à l'intérieur de lui dans la hiérarchie.

Alors maintenant, l' <Header /> est un enfant de l' <BrowserRouter> dans la <div> balises et il peut faire usage de l' Link élément.

3voto

mj sameri Points 522

Je viens 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 savait rien de Router , vous devez donc en rendre le père. composant.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X