You should not use <Link> outside a

后端 未结 10 1596
既然无缘
既然无缘 2020-11-27 15:55

I\'m trying to set up react-router in an example application, and I\'m getting the following error:

You should not use  outside a 
         


        
相关标签:
10条回答
  • 2020-11-27 15:57

    Enclose Link component inside BrowserRouter component

     export default () => (
      <div>
       <h1>
          <BrowserRouter>
            <Link to="/">Redux example</Link>
          </BrowserRouter>
        </h1>
      </div>
    )
    
    0 讨论(0)
  • 2020-11-27 15:57

    Make it simple:

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

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

    0 讨论(0)
  • 2020-11-27 16:02

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

    This error message is essentially saying that any component that is not a child of our <Router> cannot contain any React Router related components.

    You need to migrate your component hierarchy to how you see it in the first answer above. For anyone else reviewing this post who may need to look at more examples.

    Let's say you have a Header.jscomponent 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;
    

    Notice that the Header.js component is making use of the Link tag from react-router-dom but the componet was placed outside the <BrowserRouter>, this will lead to the same error as the one experience by the OP. In this case, you can make the 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 review carefully and ensure you have the <Header /> or whatever your component may be inside of not only the <BrowserRouter> but also inside of the <div>, otherwise you will also get the error that a Router may only have one child which is referring to the <div> which is the child of <BrowserRouter>. Everything else such as Route and components must go within it in the hierarchy.

    So now the <Header /> is a child of the <BrowserRouter> within the <div> tags and it can successfully make use of the Link element.

    0 讨论(0)
  • 2020-11-27 16:06

    I was getting this error because I was importing a reusable component from an npm library and the versions of react-router-dom did not match.

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

    0 讨论(0)
  • 2020-11-27 16:09

    I'm assuming that you are using React-Router V4, as you used the same in the original Sandbox Link.

    You are rendering the Main component in the call to ReactDOM.render that renders a Link and Main component is outside of Router, that's why it is throwing the error:

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

    Changes:

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

    2. Router can have only one child, so wrap all the routes in a div or Switch.

    3. React-Router V4, doesn't have the concept of nested routes, if you wants to use nested routes then define those routes directly inside that component.


    Check 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 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 react router v4

    0 讨论(0)
  • 2020-11-27 16:14

    For JEST users

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

    describe('Test suits for MyComponentWithLink', () => {
    it('should match with snapshot', () => {
    const tree = renderer
      .create(
        <BrowserRouter>
          <MyComponentWithLink/>
        </BrowserRouter>
      )
      .toJSON();
     expect(tree).toMatchSnapshot();
     });
    });
    
    0 讨论(0)
提交回复
热议问题