このチュートリアルは、Brad WestfallによるReactに関する三部構成のシリーズの最初のものです。 Bradが私にこれを投げかけたとき、彼はReactで始めるためのチュートリアルがたくさんあると指摘しましたが、そこからどこに行くべきかについてはあまり Reactを初めて使用する場合は、このイントロビデオを見ることをお勧めします。 このシリーズは、基本がオフに残す場所をピックアップします。
- :
- シリーズコード
- React-Router
- 複数のルート
- 再利用可能なレイアウト
- ネストされたルート
- IndexRoutes
- オプションのルート属性
- ルートのアンカーを作成するときは、<a href="">ではなく<Link to="">を使用する必要があります。 心配しないでください、<Link>コンポーネントを使用するとき、React Routerは最終的にDOMの通常のアンカーを提供します。 しかし、React Routerがルーティング魔法のいくつかを行うには、<Link>を使用する必要があります。
- アクティブリンク
- ブラウザ履歴
- Redirect withbrowserHistory
- ルートマッチング
- Router Demo
- webpackとBabelとのバンドル
- 非推奨の構文に注意してください
- 概要
- :
:
- Reactルーター(あなたはここにいます!)
- コンテナコンポーネント
- 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アプリを構築していたとしましょう:
このモックアップを再利用可能なセクションに分割する方法について考え始めると、このアイデアに終わるかもしれません:
ネスト可能なコンポーネントとレイアウトの観点から考えると、再利用可能な部品を作成することができます。
突然、アート部門は、アプリがユーザーを検索するためのページに似たウィジェットを検索するためのページを必要とすることを知らせます。 ユーザーリストとウィジェットリストの両方が検索ページに同じ”外観”を必要とするため、検索レイアウトを別のコンポーネントとして持つという考えは、:
検索レイアウトは、現在、検索ページのすべての種類の親テンプレートにすることができます。 また、一部のページでは検索レイアウトが必要な場合がありますが、他のページではメインレイアウトを使用せずに直接使用できます:
これは一般的な戦略であり、テンプレートシステムを使用したことがある場合は、おそらく非常に似たことをしました。 今度は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コンポーネントです。 私はちょうどそれが彼らが実行している役割だから、それらの二つを”レイアウト”と呼ぶことを選択します。
最終的には”ネストされたルート”を使用してUserList
をSearchLayout
の内側に配置し、次にMainLayout
の内側に配置します。 しかし、最初に、UserList
が親SearchLayout
内に配置されている場合、親はthis.props.children
を使用してその場所を決定します。 すべてのコンポーネントはpropとしてthis.props.children
を持っていますが、親コンポーネントがReactによって自動的にこのpropを埋めるのはコンポーネントがネストされてい 親コンポーネントではないコンポーネントの場合、this.props.children
はnull
になります。
ネストされたルート
これらのコンポーネントをネストさせるにはどうすればよいですか? ルータはルートをネストするときに私たちのためにそれを行います:
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>
に変換されます。
簡潔にするために、WidgetList
がUserList
に似ていると想像してください。
<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>
とpath
、component
を持たない必要があるかもしれません。 その理由を確認するために、この例から始めましょう:
<Route path="product/settings" component={ProductSettings} /><Route path="product/inventory" component={ProductInventory} /><Route path="product/orders" component={ProductOrders} />
/product
のpath
部分は反復的です。 繰り返しを削除するには、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:
サーバーからの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の例では、React
、ReactDOM
、およびReactRouter
はCDNのグローバル変数です。 ReactRouter
オブジェクトの中には、Router
やRoute
コンポーネントのように必要なすべての種類のものがあります。 したがって、次のように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ビデオ。
:
- Reactルーター(あなたはここにいます!)
- コンテナコンポーネント
- Redux
-