You must not use <Link> outside of <Router>

I try to configure the reaction of the router in the sample application, and I get the following error:

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

My application is configured like this:

Parent component

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

Children's / Main component

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

Any idea what I'm doing wrong here?

Here's a Sandbox link to demonstrate the problem.

+37
source share
9 answers

I assume that you are using React-Router V4 as you used the same in the Sandbox source link.

You provide the Main component in a call to ReactDOM.render which displays the Link component and the Main component is outside the Router , so it throws an error:

You must not use <Link> outside of <Router>

Changes :

  1. Use any of these routers , BrowserRouter / HashRouter, etc., because you are using React-Router V4.

  2. A router can have only one child, so wrap all routes in a div or switch .

  3. React-Router V4 does not have the concept of nested routes. If you want to use nested routes, define these routes directly inside this component.


Check out this working example with each of these changes.

Parent component:

 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 component from the route

 import React from 'react'; import { Link } from 'react-router-dom'; export default () => ( <div> <h1> <Link to="/">Redux example</Link> </h1> </div> ) 

Etc.


Also check this answer: Nested routes with v4 router response

+29
source

For JEST users

if you use Jest for testing, and this error occurs, just wrap your <BrowserRouter> component

 describe('Test suits for MyComponentWithLink', () => { it('should match with snapshot', () => { const tree = renderer .create( <BrowserRouter> <MyComponentWithLink/> </BrowserRouter> ) .toJSON(); expect(tree).toMatchSnapshot(); }); }); 
+19
source

I kind of came up with this 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')); 

I think the error was that you were rendering the Main component, and the Main component did not know anything about Router , so you should visualize its parent component.

+3
source

Component "Make a link" inside the component BrowserRouter

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

Whenever you try to show Link on a page that is outside of the BrowserRouter you will get this error.

This error message, in fact, indicates that any component that is not a child of our <Router> cannot contain any components related to the React Router.

You need to transfer the component hierarchy as you see it in the first answer above. For those who are reviewing this post, you may need to look at more examples.

Let's say you have a Header.js component that looks like this:

 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; 

And your App.js file looks like this:

 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; 

Please note that the Header.js component uses the Link Header.js react-router-dom tag, but this component was placed outside the <BrowserRouter> , this will result in the same error as the <BrowserRouter> OP. In this case, you can make a correction in one move:

 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; 

Please read carefully and make sure that you have <Header/> or something else, that your component can be inside not only <BrowserRouter> but also inside <div> , otherwise you will also get an error that the router there can only be one child. which refers to a <div> which is a child of <BrowserRouter> . Everything else, such as Route and components, must be part of it in the hierarchy.

Now <Header/> is a child of the <BrowserRouter> inside the <div> tags and can successfully use the Link element.

+1
source

Write a router instead of Basic in rendering (the last line in the code). How is ReactDOM.render (router, document.getElementById ('root'));

0
source

Make it simple:

 render(<BrowserRouter><Main /></BrowserRouter>, document.getElementById('root')); 

and don't forget: import { BrowserRouter } from "react-router-dom";

0
source

I got this error because I imported the reusable component from the npm library and the versions of react-router-dom did not match.

So make sure you use the same version in both places!

0
source

If you don’t want to change much, use the below code inside the onClick () method.

 this.props.history.push('/'); 
-nine
source

Source: https://habr.com/ru/post/1275191/


All Articles