您不应该在<Router>之外使用<Link>

A7D*_*7DC 44 jsx reactjs react-router

我正在尝试在示例应用程序中设置react-router,我收到以下错误:

You should not use <Link> outside a <Router>
Run Code Online (Sandbox Code Playgroud)

我的应用程序设置如下:

父组件

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'));
Run Code Online (Sandbox Code Playgroud)

儿童/ Main组件

export default () => (
  <div>
    <h1>
      <Link to="/">Redux example</Link>
    </h1>
  </div>
)
Run Code Online (Sandbox Code Playgroud)

知道我在这里做错了吗?

这是一个用于演示问题的Sandbox链接.

May*_*kla 30

我假设您使用的是React-Router V4,就像您在原始Sandbox Link中使用的那样.

Main在调用ReactDOM.render中呈现Link组件,呈现a 和Main组件在其外部Router,这就是它抛出错误的原因:

您不应该在<Router>之外使用<Link>

变化:

  1. 使用这些路由器,BrowserRouter/HashRouter等中的任何一个...,因为您使用的是React-Router V4.

  2. 路由器只能有一个子节点,所以将所有路由包装在一个divSwitch中.

  3. React-Router V4没有嵌套路由的概念,如果你想使用嵌套路由,那么直接在该组件内定义那些路由.


使用这些更改检查此工作示例.

父组件:

const App = () => (
  <BrowserRouter>
    <div className="sans-serif">
      <Route path="/" component={Main} />
      <Route path="/view/:postId" component={Single} />
    </div>
  </BrowserRouter>
);

render(<App />, document.getElementById('root'));
Run Code Online (Sandbox Code Playgroud)

Main 来自路线的组件

import React from 'react';
import { Link } from 'react-router-dom';

export default () => (
  <div>
    <h1>
      <Link to="/">Redux example</Link>
    </h1>
  </div>
)
Run Code Online (Sandbox Code Playgroud)

等等.


另请检查以下答案:使用react router v4的嵌套路由


MBe*_*mam 22

对于JEST用户

如果您使用Jest进行测试,并且发生此错误,则只需用 <BrowserRouter>

describe('Test suits for MyComponentWithLink', () => {
it('should match with snapshot', () => {
const tree = renderer
  .create(
    <BrowserRouter>
      <MyComponentWithLink/>
    </BrowserRouter>
  )
  .toJSON();
 expect(tree).toMatchSnapshot();
 });
});
Run Code Online (Sandbox Code Playgroud)

  • 你救了我。谢谢 (6认同)
  • 将其包装在“&lt;MemoryRouter&gt;”而不是“&lt;BrowserRouter&gt;”中,因为“&lt;MemoryRouter&gt;”重量更轻。 (3认同)
  • 正是我正在寻找的东西。谢谢 (2认同)
  • 这个答案使用“react-test-renderer”,它不是为 create-react-app 内置的。如果您使用内置的`@testing-library/react`,请改用`render(&lt;BrowserRouter&gt;&lt;MyComponent/&gt;&lt;/BrowserRouter&gt;);`。 (2认同)

Dan*_*iel 14

每当您尝试Link在 之外的页面上显示 a时,BrowserRouter您都会收到该错误。

此错误消息本质上是说任何不是我们的子组件的组件<Router>都不能包含任何与 React Router 相关的组件。

您需要将您的组件层次结构迁移到您在上面第一个答案中看到的样子。对于可能需要查看更多示例的其他人查看此帖子。

假设您有一个如下所示的Header.js组件:

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;
Run Code Online (Sandbox Code Playgroud)

您的App.js文件如下所示:

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;
Run Code Online (Sandbox Code Playgroud)

请注意,该Header.js组件正在使用Linkfrom 标记,react-router-dom但该组件被放置在 之外<BrowserRouter>,这将导致与 OP 体验相同的错误。在这种情况下,您可以一步进行更正:

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;
Run Code Online (Sandbox Code Playgroud)

请仔细检查并确保您<Header />的组件不仅在<BrowserRouter>内,而且在 内<div>,否则您还会收到错误,即路由器可能只有一个子项,<div>该子项指的是 的子项<BrowserRouter>. 其他所有东西,比如Route和 组件,都必须在层次结构中。

所以现在<Header />是标签<BrowserRouter>内的子<div>元素,它可以成功地使用Link元素。


Bas*_*ani 5

将Link组件包含在BrowserRouter组件内

 export default () => (
  <div>
   <h1>
      <BrowserRouter>
        <Link to="/">Redux example</Link>
      </BrowserRouter>
    </h1>
  </div>
)
Run Code Online (Sandbox Code Playgroud)


Iva*_*roz 5

让它变得简单:

render(<BrowserRouter><Main /></BrowserRouter>, document.getElementById('root'));
Run Code Online (Sandbox Code Playgroud)

并且不要忘记:import { BrowserRouter } from "react-router-dom";