サンプルアプリケーションで反応ルーターを設定しようとしていますが、次のエラーが表示されます。
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>
)
ここで私が間違っていることは何ですか?
これはサンドボックスリンクです 問題を示します。
元の Sandbox Link。 で同じものを使用したため、React-Router V4を使用していると想定しています。
Main
をレンダリングするReactDOM.render
への呼び出しでLink
コンポーネントをレンダリングしており、メインコンポーネントがRouter
の外側にあるため、エラーがスローされています。
<Router>の外部で<Link>を使用しないでください。
変更:
React-Router V4を使用しているため、これらのルーター、BrowserRouter/HashRouterなどのいずれかを使用します。
ルーターは子を1つしか持つことができないため、すべてのルートを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>
)
等。
この回答も確認してください: react router v4のネストされたルート
JESTユーザーの場合
テストにJestを使用し、このエラーが発生した場合、コンポーネントを<BrowserRouter>
でラップするだけです
describe('Test suits for MyComponentWithLink', () => {
it('should match with snapshot', () => {
const tree = renderer
.create(
<BrowserRouter>
<MyComponentWithLink/>
</BrowserRouter>
)
.toJSON();
expect(tree).toMatchSnapshot();
});
});
私はちょっとこのコードを思いつきます:
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
について何も知らなかったため、その親コンポーネントをレンダリングする必要があるためだと思います。
Link
の外側にあるページにBrowserRouter
を表示しようとすると、そのエラーが発生します。
このエラーメッセージは基本的に、<Router>
の子ではないコンポーネントにはReactルーター関連のコンポーネントを含めることができないことを示しています。
コンポーネントの階層を、上記の最初の回答で見たとおりに移行する必要があります。この投稿をレビューしている他の人のために、もっと例を見る必要があるかもしれません。
次のようなHeader.js
componentがあるとします:
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
コンポーネントがreact-router-dom
のLink
タグを使用しているが、コンポーネントが<BrowserRouter>
の外側に配置されていることに注意してください。これにより、1つのエクスペリエンスと同じエラーが発生しますOPによって。この場合、1回の動作で修正を行うことができます。
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>
を参照している子は1つだけです。 Route
やコンポーネントなど、他のすべてのものは、階層内でその中に入る必要があります。
したがって、<Header />
は<BrowserRouter>
タグ内の<div>
の子であり、Link
要素を正常に使用できます。
BrowserRouterコンポーネント内にLinkコンポーネントを含める
export default () => (
<div>
<h1>
<BrowserRouter>
<Link to="/">Redux example</Link>
</BrowserRouter>
</h1>
</div>
)
それを簡単に:
render(<BrowserRouter><Main /></BrowserRouter>, document.getElementById('root'));
忘れないでください:import { BrowserRouter } from "react-router-dom";
render(コードの最後の行)のMainの代わりにrouterと記述します。このようにReactDOM.render(router、document.getElementById( 'root'));