我试图在示例应用程序中设置react-router,并且我收到以下错误:
Main
我的应用设置如下:
export default () => (
<div>
<h1>
<Link to="/">Redux example</Link>
</h1>
</div>
)
this.getView().byId(...)
组件this.byId(...)
知道我在这里做错了吗?
Here's a Sandbox link来证明这个问题。
答案 0 :(得分:19)
我假设您正在使用React-Router V4,因为您在原始Sandbox Link.
中使用了相同的方法您在Main
的调用中呈现ReactDOM.render
组件,其呈现Link
而主要组件位于Router
之外,这就是为什么它是抛出错误:
您不应该使用&lt; Link&gt;在&lt;路由器&gt;
之外
<强>更改强>:
使用 these Routers ,BrowserRouter / HashRouter等中的任何一个......,因为您使用的是React-Router V4。
路由器只能有一个子节点,因此请将所有路由包裹在div
或Switch中。
React-Router V4,没有嵌套路由的概念,如果你想使用嵌套路由,那么直接在该组件内定义那些路由。
使用以下每项更改检查 this working example 。
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
组件
import React from 'react';
import { Link } from 'react-router-dom';
export default () => (
<div>
<h1>
<Link to="/">Redux example</Link>
</h1>
</div>
)
等
同时查看以下答案:Nested routes with react router v4
答案 1 :(得分:8)
对于JEST用户
如果您使用Jest进行测试,并且发生了此错误,只需用<BrowserRouter>
包裹您的组件
describe('Test suits for MyComponentWithLink', () => {
it('should match with snapshot', () => {
const tree = renderer
.create(
<BrowserRouter>
<MyComponentWithLink/>
</BrowserRouter>
)
.toJSON();
expect(tree).toMatchSnapshot();
});
});
答案 2 :(得分:3)
我有点想出这个代码:
Main
我认为错误是因为您正在呈现Main
组件,而Router
组件对array
一无所知,因此您必须呈现其父组件。< / p>
答案 3 :(得分:1)
将Link组件包含在BrowserRouter组件内
export default () => (
<div>
<h1>
<BrowserRouter>
<Link to="/">Redux example</Link>
</BrowserRouter>
</h1>
</div>
)
答案 4 :(得分:1)
每当您尝试在Link
以外的页面上显示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;
您的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;
请注意,Header.js
组件正在使用Link
中的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;
请仔细检查并确保您拥有<Header />
或任何组件,不仅包含在<BrowserRouter>
内,而且还包含在<div>
内,否则您将收到错误消息路由器可能只有一个孩子,而孩子是指<div>
的孩子。 <BrowserRouter>
之类的所有其他内容和组件都必须位于层次结构中。
因此,现在Route
是<Header />
标记内<BrowserRouter>
的子代,它可以成功利用<div>
元素。
答案 5 :(得分:1)
简单点:
render(<BrowserRouter><Main /></BrowserRouter>, document.getElementById('root'));
不要忘记:import { BrowserRouter } from "react-router-dom";
答案 6 :(得分:0)
在渲染(代码中的最后一行)中写路由器代替主。 像这样 ReactDOM.render(router,document.getElementById(&#39; root&#39;));
答案 7 :(得分:0)
我收到此错误是因为我正在从npm库中导入可重用组件,而react-router-dom
的版本不匹配。
因此请确保您在两个地方都使用相同的版本!
答案 8 :(得分:0)
您可以将Link组件放置在Router组件内。像这样:
<Router>
<Route path='/complete-profiles' component={Profiles} />
<Link to='/complete-profiles'>
<div>Completed Profiles</div>
</Link>
</Router>
答案 9 :(得分:0)
我的回答基于此 article。这是一个简单的解决方案。
// index.test.tsx
import React from "react";
import { render, screen } from "@testing-library/react";
import { Router } from "react-router-dom";
import { createBrowserHistory } from "history";
import Login from ".";
it("should display Login", () => {
const history = createBrowserHistory();
render(
<Router history={history}>
<Login />
</Router>
);
const linkElement = screen.getByText(/Login/i);
expect(linkElement).toBeInTheDocument();
});
答案 10 :(得分:0)
为什么不尝试创建另一个仅使用“react-router-dom”中的 BrowserRouter 的组件,并将您的组件与其中的 Link 一起包装起来。
const ReduxExample () => (
<div>
<h1>
<Link to="/">Redux example</Link>
</h1>
</div>
)
然后你可以这样做
const NewReduxExample = () => {
<BrowserRouter>
<ReduxExample />
</BrowserRouter>
};
答案 11 :(得分:-8)
如果您不想改变太多,请在onClick()方法中使用以下代码。
this.props.history.push('/');