React Router

このチュートリアルは、Brad WestfallによるReactに関する三部構成のシリーズの最初のものです。 Bradが私にこれを投げかけたとき、彼はReactで始めるためのチュートリアルがたくさんあると指摘しましたが、そこからどこに行くべきかについてはあまり Reactを初めて使用する場合は、このイントロビデオを見ることをお勧めします。 このシリーズは、基本がオフに残す場所をピックアップします。

:

  1. Reactルーター(あなたはここにいます!)
  2. コンテナコンポーネント
  3. Redux

ツづツつキツ。 この記事はReact Router4より前に書かれたもので、Reactでのルーティングのためのより標準的な選択肢となっています。 React Router4をカバーする新しい記事がありますここであなたは間違いなく読むべきです。

私が最初に学んでいたとき、私は単一のコンポーネントを作成し、DOMにレンダリングする方法を示した初心者ガイド(すなわち1、2、3、4)の多くを見つ 彼らはJSXや小道具のような基本を教える素晴らしい仕事をしましたが、私はReactが実際の単一ページアプリケーション(SPA)のように、より大きな画像でどのよ このシリーズは多くの資料をカバーしているので、絶対的な初心者の概念はカバーしません。 代わりに、少なくとも一つのコンポーネントを作成してレンダリングする方法を既に理解しているという前提から始めます。

それは価値があるもののために、ここでは初心者を目指すいくつかの他の偉大なガイドがあります:

  • 反応する。jsとそれは他のすべてとどのように適合しますか?
  • 再考(業界)ベストプラクティス
  • React.js入門

シリーズコード

で取得するだけのjQueryを知っている人のためのこのシリーズには、GitHubで遊ぶためのコードもいくつか付属しています。 シリーズを通して、ユーザーとウィジェットに焦点を当てた基本的なSPAを構築します。シンプルで簡潔にするために、このシリーズの例では、ReactとReact RouterがCDNから取得されると仮定することから始めます。 したがって、以下の直接の例ではrequire()またはimportは表示されません。 しかし、このチュートリアルの最後に向けて、GitHubガイドのためにWebpackとBabelを紹介します。 その時点で、それはすべてES6です!

React-Router

Reactはフレームワークではなく、ライブラリです。 したがって、すべてのアプリケーションのニーズを解決するわけではありません。 コンポーネントを作成し、状態を管理するためのシステムを提供することは素晴らしい仕事ですが、より複雑なSPAを作成するにはサポートキャストが必 最初に見るのはReact Routerです。

以前にフロントエンドルーターを使用したことがある場合、これらの概念の多くはよく知られています。 しかし、以前に使用した他のルーターとは異なり、React RouterはJSXを使用していますが、これは最初は少し奇妙に見えるかもしれません。

プライマーとして、これは単一のコンポーネントをレンダリングするようなものです:

var Home = React.createClass({ render: function() { return (<h1>Welcome to the Home Page</h1>); }});ReactDOM.render(( <Home />), document.getElementById('root'));

React RouterでHomeコンポーネントをレンダリングする方法は次のとおりです:

...ReactDOM.render(( <Router> <Route path="/" component={Home} /> </Router>), document.getElementById('root'));

<Router><Route>は二つの異なるものであることに注意してください。 それらは技術的にはReactコンポーネントですが、実際にはDOM自体を作成しません。 <Router>自体が'root'にレンダリングされているように見えるかもしれませんが、実際にはアプリケーションの動作に関するルールを定義しているだけです。 今後、この概念は頻繁に表示されます: コンポーネントは、DOM自体を作成するためではなく、他のコンポーネントを調整するために存在することがあります。

この例では、<Route>はホームページ/にアクセスするとHomeコンポーネントが'root'にレンダリングされるルールを定義しています。

複数のルート

前の例では、単一のルートは非常に簡単です。 ルーターを使用せずにHomeコンポーネントをレンダリングする機能が既にあるため、それほど価値はありません。

React Routerのパワーは、複数のルートを使用して、現在アクティブなパスに基づいてどのコンポーネントをレンダリングすべきかを定義するときに:

ReactDOM.render(( <Router> <Route path="/" component={Home} /> <Route path="/users" component={Users} /> <Route path="/widgets" component={Widgets} /> </Router>), document.getElementById('root'));

<Route>は、そのパスがURLと一致すると、それぞれのコンポーネントをレンダリングします。 これらの3つのコンポーネントのうちの1つだけが、いつでも'root'にレンダリングされます。 この戦略では、ルータをDOM'root'に一度マウントし、ルータはルートの変更でコンポーネントを交換します。

ルータがサーバに要求を行わずにルートを切り替えることにも注目する価値があるので、各コンポーネントがまったく新しいページになると想像してくださ

再利用可能なレイアウト

私たちは、単一のページアプリケーションの謙虚な始まりを見始めています。 しかし、それはまだ現実世界の問題を解決しません。 確かに、私たちは完全なHTMLページになるように三つのコンポーネントを構築することができますが、コードの再利用はどうですか? これらの3つのコンポーネントは、ヘッダーやサイドバーのような共通のアセットを共有している可能性がありますが、どのようにして各コンポーネ

このモックアップに似たwebアプリを構築していたとしましょう:

シンプルなウェブサイトのモックアップ。

このモックアップを再利用可能なセクションに分割する方法について考え始めると、このアイデアに終わるかもしれません:

単純なwebモックアップをセクションに分割する方法。

ネスト可能なコンポーネントとレイアウトの観点から考えると、再利用可能な部品を作成することができます。

突然、アート部門は、アプリがユーザーを検索するためのページに似たウィジェットを検索するためのページを必要とすることを知らせます。 ユーザーリストとウィジェットリストの両方が検索ページに同じ”外観”を必要とするため、検索レイアウトを別のコンポーネントとして持つという考えは、:

ユーザーの代わりにウィジェットを今すぐ検索しますが、親セクションは同じままです。

検索レイアウトは、現在、検索ページのすべての種類の親テンプレートにすることができます。 また、一部のページでは検索レイアウトが必要な場合がありますが、他のページではメインレイアウトを使用せずに直接使用できます:

レイアウトがデカップリングされました。

これは一般的な戦略であり、テンプレートシステムを使用したことがある場合は、おそらく非常に似たことをしました。 今度はHTMLで作業しましょう。 まず、JavaScriptを考慮せずに静的HTMLを実行します:

<div> <!-- Main Layout --> <div class="app"> <header class="primary-header"><header> <aside class="primary-aside"></aside> <main> <!-- Search Layout --> <div class="search"> <header class="search-header"></header> <div class="results"> <!-- User List --> <ul class="user-list"> <li>Dan</li> <li>Ryan</li> <li>Michael</li> </ul> </div> <div class="search-footer pagination"></div> </div> </main> </div></div>

覚えておいてください、'root'要素は、JavaScriptが開始する前に最初のHTML本文が持つ唯一の要素であるため、常に存在します。 Reactアプリケーション全体がマウントされるため、”root”という言葉が適切です。 しかし、あなたがそれを呼ぶものには「正しい名前」や慣習はありません。 私は”root”を選択したので、私たちは例を通してそれを使用し続けます。 ただ、<body>要素に直接マウントすることは非常にお勧めしませんので注意してください。

静的HTMLを作成した後、それをReactコンポーネントに変換します:

var MainLayout = React.createClass({ render: function() { // Note the `className` rather than `class` // `class` is a reserved word in JavaScript, so JSX uses `className` // Ultimately, it will render with a `class` in the DOM return ( <div className="app"> <header className="primary-header"><header> <aside className="primary-aside"></aside> <main> {this.props.children} </main> </div> ); }});var SearchLayout = React.createClass({ render: function() { return ( <div className="search"> <header className="search-header"></header> <div className="results"> {this.props.children} </div> <div className="search-footer pagination"></div> </div> ); }});var UserList = React.createClass({ render: function() { return ( <ul className="user-list"> <li>Dan</li> <li>Ryan</li> <li>Michael</li> </ul> ); }});

私が”レイアウト”と”コンポーネント”と呼んでいるものの間にあまりにも気を取らないでください。 これらの3つはすべてReactコンポーネントです。 私はちょうどそれが彼らが実行している役割だから、それらの二つを”レイアウト”と呼ぶことを選択します。

最終的には”ネストされたルート”を使用してUserListSearchLayoutの内側に配置し、次にMainLayoutの内側に配置します。 しかし、最初に、UserListが親SearchLayout内に配置されている場合、親はthis.props.childrenを使用してその場所を決定します。 すべてのコンポーネントはpropとしてthis.props.childrenを持っていますが、親コンポーネントがReactによって自動的にこのpropを埋めるのはコンポーネントがネストされてい 親コンポーネントではないコンポーネントの場合、this.props.childrennullになります。

ネストされたルート

これらのコンポーネントをネストさせるにはどうすればよいですか? ルータはルートをネストするときに私たちのためにそれを行います:

ReactDOM.render(( <Router> <Route component={MainLayout}> <Route component={SearchLayout}> <Route path="users" component={UserList} /> </Route> </Route> </Router>), document.getElementById('root'));

コンポーネントは、ルータがルートをネストする方法に従ってネストされます。 ユーザーが/usersルートを訪問すると、React RouterはUserListコンポーネントをSearchLayoutの中に配置し、その後両方をMainLayoutの中に配置します。 /usersを訪問した最終結果は、'root'の中に配置された三つのネストされたコンポーネントになります。

ユーザーがホームページのパス(/)にアクセスしたり、ウィジェットを検索したりするときのルールがないことに注意してください。 それらは簡単にするために除外されましたが、新しいルータでそれらを入れてみましょう:

ReactDOM.render(( <Router> <Route component={MainLayout}> <Route path="/" component={Home} /> <Route component={SearchLayout}> <Route path="users" component={UserList} /> <Route path="widgets" component={WidgetList} /> </Route> </Route> </Router>), document.getElementById('root'));

あなたはおそらく、JSXがRouteコンポーネントが一つのタグとして書くことができるという意味でXMLルールに従うことに気づいたでしょう:<Route />または2つ:<Route>...</Route>。 これは、カスタムコンポーネントと通常のDOMノードを含むすべてのJSXに当てはまります。 たとえば、<div />は有効なJSXであり、レンダリング時に<div></div>に変換されます。

簡潔にするために、WidgetListUserListに似ていると想像してください。

<Route component={SearchLayout}>には2つの子ルートがあるため、ユーザーは/usersまたは/widgetsにアクセスでき、対応する<Route>はそれぞれのコンポーネントをSearchLayoutコンポーネント内にロードします。

また、HomeコンポーネントがMainLayoutの内部に直接配置され、SearchLayoutが関与しないことに注意してください。<Route>がネストされているためです。 ルートを並べ替えることで、レイアウトやコンポーネントのネスト方法を簡単に並べ替えることができます。

IndexRoutes

React Routerは非常に表現力があり、同じことを行う方法が複数あることがよくあります。 例えば、我々はまた、このような上記のルータを書いている可能性があります:

ReactDOM.render(( <Router> <Route path="/" component={MainLayout}> <IndexRoute component={Home} /> <Route component={SearchLayout}> <Route path="users" component={UserList} /> <Route path="widgets" component={WidgetList} /> </Route> </Route> </Router>), document.getElementById('root'));

その異なる外観にもかかわらず、彼らは両方ともまったく同じように動作します。

オプションのルート属性

場合によっては、<Route>には、上からのSearchLayoutルートのように、pathのないcomponent属性があります。 それ以外の場合は、<Route>pathcomponentを持たない必要があるかもしれません。 その理由を確認するために、この例から始めましょう:

<Route path="product/settings" component={ProductSettings} /><Route path="product/inventory" component={ProductInventory} /><Route path="product/orders" component={ProductOrders} />

/productpath部分は反復的です。 繰り返しを削除するには、3つのルートすべてを新しいルートにラップします<Route>:

<Route path="product"> <Route path="settings" component={ProductSettings} /> <Route path="inventory" component={ProductInventory} /> <Route path="orders" component={ProductOrders} /></Route>

ここでも、React Routerはその表現力を示しています。 クイズ:あなたは両方の解決策の問題に気づきましたか? 現時点では、ユーザーが/productパスを訪問したときのルールはありません。

これを修正するには、次のように追加しますIndexRoute:

<Route path="product"> <IndexRoute component={ProductProfile} /> <Route path="settings" component={ProductSettings} /> <Route path="inventory" component={ProductInventory} /> <Route path="orders" component={ProductOrders} /></Route>

ルートのアンカーを作成するときは、<a href="">ではなく<Link to="">を使用する必要があります。 心配しないでください、<Link>コンポーネントを使用するとき、React Routerは最終的にDOMの通常のアンカーを提供します。 しかし、React Routerがルーティング魔法のいくつかを行うには、<Link>を使用する必要があります。

私たちのMainLayoutにいくつかのリンク(アンカー)を追加してみましょう:

var MainLayout = React.createClass({ render: function() { return ( <div className="app"> <header className="primary-header"></header> <aside className="primary-aside"> <ul> <li><Link to="/">Home</Link></li> <li><Link to="/users">Users</Link></li> <li><Link to="/widgets">Widgets</Link></li> </ul> </aside> <main> {this.props.children} </main> </div> ); }});

<Link>コンポーネントの属性は、作成したアンカーに渡されます。 だから、このJSX:

<Link to="/users" className="users">

DOMでこれになります:

<a href="/users" class="users">

外部のwebサイトなど、ルータパス以外のアンカーを作成する必要がある場合は、通常のアンカータグを通常どおり使用します。 詳細については、IndexRouteおよびLinkのドキュメントを参照してください。

アクティブリンク

<Link>コンポーネントの優れた機能は、いつアクティブになっているかを知ることです:

<Link to="/users" activeClassName="active">Users</Link>

ユーザが/usersパス上にいる場合、ルータは<Link>で作成された一致するアンカーを探し出し、activeクラスを切り替えます。 この機能の詳細を参照してください。ブラウザ履歴

ブラウザ履歴

混乱を防ぐために、今まで重要な詳細を省いてきました。 <Router>は、どの履歴追跡戦略を使用するかを知る必要があります。 React Router docsは、次のように実装されているbrowserHistoryをお勧めします:

var browserHistory = ReactRouter.browserHistory;ReactDOM.render(( <Router history={browserHistory}> ... </Router>), document.getElementById('root'));

以前のバージョンのReact Routerでは、history属性は必須ではなく、デフォルトではhashHistoryを使用していました。 名前が示すように、バックボーンに期待されるものと同様に、URLに#ハッシュ記号を使用してフロントエンドSPAスタイルのルーティングを管理しました。jsルーター。

hashHistoryでは、Urlは次のようになります:

  • example.com
  • example.com/#/users?_k=ckuvup
  • example.com/#/widgets?_k=ckuvup

しかし、それらの醜いクエリ文字列はどうなっていますか?

browserHistoryが実装されている場合、パスはより有機的に見えます:

  • example.com
  • example.com/users
  • com/widgets

フロントエンドでbrowserHistoryが使用されている場合、サーバーには警告があります。 ユーザーがexample.comで訪問を開始し、/usersおよび/widgetsに移動すると、React Routerはこのシナリオを期待どおりに処理します。 ただし、ユーザーがブラウザに直接example.com/widgetsと入力して訪問を開始する場合、またはexample.com/widgetsで更新する場合、ブラウザは/widgetsの少なくとも1つの要求をサーバーに送信する必 しかし、サーバー側のルータがない場合、これはaを提供します404:

Urlには注意してください。 サーバー側のルーターが必要です。

サーバーからの404の問題を解決するために、React Routerはサーバー側でワイルドカードルーターを推奨しています。 この戦略では、どのサーバー側ルートが呼び出されても、サーバーは常に同じHTMLファイルを提供する必要があります。 次に、ユーザーがexample.com/widgetsで直接起動した場合、同じHTMLファイルが返されても、React Routerは正しいコンポーネントをロードするのに十分スマートです。

ユーザーは奇妙なことに気付くことはありませんが、常に同じHTMLファイルを提供することについて懸念があるかもしれません。 コード例では、このシリーズでは引き続き”ワイルドカードルーター”戦略を使用しますが、サーバー側のルーティングを適切な方法で処理するのはユーザー次第です。 React Routerは、サーバー側とクライアント側の両方で同形の方法で使用できますか? 確かにそれはできますが、それはこのチュートリアルの範囲を超えています。

Redirect withbrowserHistory

browserHistoryオブジェクトはシングルトンなので、任意のファイルに含めることができます。 コードのいずれかでユーザーを手動でリダイレクトする必要がある場合は、pushメソッドを使用してこれを行うことができます:

browserHistory.push('/some/path');

ルートマッチング

React routerは他のルーターと同様にルートマッチングを処理します:

<Route path="users/:userId" component={UserProfile} />

このルートは、ユーザーがusers/で始まり、その後の値を持つ任意のパスを訪問したときに一致します。 それは/users/1/users/143、または/users/abc(あなた自身で検証する必要があります)と一致します。

React Routerは:userIdの値をpropとしてUserProfileに渡します。 この小道具はthis.props.params.userId内のUserProfileとしてアクセスされます。

Router Demo

この時点で、デモを表示するのに十分なコードがあります。

CodePenのBrad Westfall(@bradwestfall)によるPen React-Routerデモを参照してください。

この例でいくつかのルートをクリックすると、ブラウザの戻るボタンと進むボタンがルータで動作することがあります。 これは、これらのhistory戦略が存在する主な理由の一つです。 また、訪問する各ルートでは、最初のHTMLを取得する最初のものを除いて、サーバーに要求が行われないことに注意してください。 それはどのようにクールですか?CodePenの例では、ReactReactDOM、およびReactRouterはCDNのグローバル変数です。 ReactRouterオブジェクトの中には、RouterRouteコンポーネントのように必要なすべての種類のものがあります。 したがって、次のようにReactRouterを使用できます:

ReactDOM.render(( <ReactRouter.Router> <ReactRouter.Route ... /> </ReactRouter.Router>), document.getElementById('root'));

ここでは、すべてのルーターコンポーネントの前に親オブジェクトReactRouterを付ける必要があります。 または、ES6の新しい破壊構文を次のように使用することもできます:

var { Router, Route, IndexRoute, Link } = ReactRouter

これは、ReactRouterの部分を通常の変数に”抽出”して、それらに直接アクセスできるようにします。

ここから、このシリーズの例では、destructuring、spread演算子、imports/exports、およびおそらく他のものを含むさまざまなES6構文を使用します。 新しい構文が表示されるたびに簡単な説明があり、このシリーズに付属のGitHubレポにはES6の説明もたくさんあります。

webpackとBabelとのバンドル

前に述べたように、このシリーズにはGitHubリポジトリが付属しているので、コードを試すことができます。 それは現実世界のスパの素質に似ているので、webpackやBabelのようなツールを使用します。

  • webpackはブラウザ用に複数のJavaScriptファイルを一つのファイルにバンドルします。ほとんどのブラウザはまだすべてのES6を理解していないため、BabelはES6(ES2015)コードをES5に変換します。 この記事が古くなるにつれて、ブラウザはES6をサポートし、Babelは必要ないかもしれません。これらのツールをまだ使い慣れていない場合は、サンプルコードにはすべてが設定されているため、Reactに集中できます。 しかし、サンプルコードを確認してくださいREADME.md 追加のワークフロー文書用のファイル。

    非推奨の構文に注意してください

    React Routerに関する情報をGoogleで検索すると、React Routerが1.0より前のリリースにあったときに書かれた多くの記事やStackOverflowページ プレ1からの多くの機能。0リリースは非推奨になりました。 ここに短いリストがあります:

    • <Route name="" /> は非推奨です。 代わりに<Route path="" />を使用してください。
    • <Route handler="" />は非推奨です。 代わりに<Route component="" />を使用してください。
    • <NotFoundRoute />は非推奨です。 代替案
    • <RouteHandler />は非推奨です。
    • willTransitionToは非推奨です。 OnEnter
    • willTransitionFromは非推奨です。 OnLeave
    • を参照してください”場所”は現在”歴史”と呼ばれています。

    1.0.0と2.0.0の完全なリストを参照してください

    概要

    React Routerにはまだ表示されていない機能がありますので、API Docsをチェックしてくださ React Routerの作成者は、React Routerのステップバイステップのチュートリアルも作成しており、このReactもチェックアウトしています。React Routerがどのように作成されたかについてのjs Confビデオ。

    :

    1. Reactルーター(あなたはここにいます!)
    2. コンテナコンポーネント
    3. Redux

コメントを残す

メールアドレスが公開されることはありません。