Вы не должны использовать <Link> вне <Router>
Я пытаюсь настроить реакцию маршрутизатора в примере приложения, и я получаю следующую ошибку:
You should not use <Link> outside a <Router>
Мое приложение настроено так:
Родительский компонент
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'));
Детский /Main
компонент
export default () => (
<div>
<h1>
<Link to="/">Redux example</Link>
</h1>
</div>
)
Есть идеи, что я здесь делаю не так?
Здесь ссылка Песочница, чтобы продемонстрировать проблему.
Ответы
Ответ 1
Я предполагаю, что вы используете React-Router V4, как вы использовали то же самое в исходной ссылке Sandbox.
Вы предоставляете компонент Main
в вызове ReactDOM.render
который отображает компонент Link
а компонент Main находится за пределами Router
, поэтому он выдает ошибку:
Вы не должны использовать <Link> вне <Router>
Изменения:
-
Используйте любой из этих маршрутизаторов, BrowserRouter/HashRouter и т.д., Потому что вы используете React-Router V4.
-
Маршрутизатор может иметь только одного дочернего элемента, поэтому оберните все маршруты в div
или Switch.
-
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'));
Main
компонент из маршрута
import React from 'react';
import { Link } from 'react-router-dom';
export default () => (
<div>
<h1>
<Link to="/">Redux example</Link>
</h1>
</div>
)
И т.п.
Также проверьте этот ответ: Вложенные маршруты с реакции маршрутизатора v4
Ответ 2
Для пользователей JEST
если вы используете Jest для тестирования, и эта ошибка возникает, просто оберните ваш компонент <BrowserRouter>
describe('Test suits for MyComponentWithLink', () => {
it('should match with snapshot', () => {
const tree = renderer
.create(
<BrowserRouter>
<MyComponentWithLink/>
</BrowserRouter>
)
.toJSON();
expect(tree).toMatchSnapshot();
});
});
Ответ 3
Я вроде придумала этот код:
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'));
Я думаю, что ошибка была в том, что вы выполняли рендеринг компонента Main
, а компонент Main
ничего не знал о Router
, поэтому вы должны визуализировать его родительский компонент.
Ответ 4
Компонент "Заключить ссылку" внутри компонента BrowserRouter
export default () => (
<div>
<h1>
<BrowserRouter>
<Link to="/">Redux example</Link>
</BrowserRouter>
</h1>
</div>
)
Ответ 5
Всякий раз, когда вы пытаетесь показать 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
Header.js
react-router-dom
но этот компонент был размещен вне <BrowserRouter>
, это приведет к той же ошибке, что и <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>
и может успешно использовать элемент Link
.
Ответ 6
Напишите маршрутизатор вместо Основной в рендеринг (последняя строка в коде).
Как это
ReactDOM.render(маршрутизатор, document.getElementById('root'));
Ответ 7
Сделайте это просто:
render(<BrowserRouter><Main /></BrowserRouter>, document.getElementById('root'));
и не забудь: import { BrowserRouter } from "react-router-dom";
Ответ 8
Я получил эту ошибку, потому что я импортировал повторно используемый компонент из библиотеки npm, а версии react-router-dom
не совпадали.
Поэтому убедитесь, что вы используете одну и ту же версию в обоих местах!
Ответ 9
Если вы не хотите сильно меняться, используйте ниже код внутри метода onClick().
this.props.history.push('/');