ReactRouterv4で条件付きおよびレスポンシブルーティングを設定する方法
序章
Reactのレスポンシブルーティングには、デバイスのビューポートに基づいてユーザーにさまざまなルートを提供することが含まれます。 これを実現するために通常CSSメディアクエリが使用されますが、これにより、CSSプロップを使用してさまざまな要素を表示するかどうかを制限できます。 レスポンシブルートを使用すると、画面サイズに直接基づいて、Reactアプリケーションの個別のビュー全体をさまざまなユーザーに提供できるようになりました。
このチュートリアルでは、Reactアプリケーションにルーティングとレスポンシブルートの提供を実装する方法を示します。 このチュートリアルに従うことで、デバイス画面のサイズに基づいてユーザーにさまざまなルートを提供するユーザーダッシュボードアプリケーションを構築します。
前提条件
このチュートリアルを完了するには、次のものが必要です。
- Node.jsはローカルにインストールされます。これは、Node.jsのインストール方法とローカル開発環境の作成に従って実行できます。
このチュートリアルは、ノードv14.2.0、npm
v6.14.5、react
v16.3.2、react-router-dom
v5.2.0、およびreact-media
v1.10.0で検証されました。 。
ステップ1—プロジェクトの設定
プロジェクトを開始するには、npx
とcreate-react-app を使用して、新しいReactアプリケーションを作成します。
- npx create-react-app responsive-routing
次に、新しいプロジェクトディレクトリに移動します。
- cd responsive-routing
次に、このデモを正常にビルドするために必要なモジュールをインストールします。 これらのモジュールは、react-router-dom
およびreact-media
です。 次のコマンドを実行して、これらをインストールできます。
- npm install react-router-dom@5.2.0 react-media@1.10.0
これで、次のコマンドを実行してアプリケーションを起動できます。
- npm start
注:ルーティングには必要ありませんが、このチュートリアルでは、スタイリングとレイアウトに BulmaCSSフレームワークを使用します。
次のターミナルコマンドでブルマを追加できます。
- npm install bulma@0.6.2
そして、index.js
に以下を追加します。
import 'bulma/css/bulma.css';
このステップでは、プロジェクトをセットアップし、スタイリングとレイアウトのためのBulmaフレームワークを追加しました。
ステップ2—Reactルーターを追加する
プロジェクトにルーティングを追加するには、index.js
ファイルを変更して、ルーターを要素階層のルートにレンダリングする必要があります。
- nano index.js
まず、BrowserRouter
をreact-router-dom
からインポートし、Router
にエイリアスします。
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter as Router } from "react-router-dom";
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
次に、<React>
を<Router>
に置き換えます。
ReactDOM.render(
<Router>
<App />
</Router>,
document.getElementById('root')
);
これで、アプリケーションはReactRouterを使用するように設定されました。
ステップ3—Nav
コンポーネントを作成する
ページの中央にあるGitHubロゴは、アプリケーションのナビゲーション部分として機能します。
src
ディレクトリに、Nav
という名前の新しいディレクトリを作成します。
- mkdir src/Nav
GitHubロゴを追加し、このディレクトリにlogo.svg
として保存する必要があります。
次に、このディレクトリにindex.js
ファイルを作成します。
- nano src/Nav/index.js
そして、次のコードを追加します。
import React from 'react';
import './Nav.css';
import logo from './logo.svg';
const Nav = () => (
<nav>
<img src={logo} alt="Logo" />
</nav>
);
export default Nav;
次に、このディレクトリにNav.css
ファイルを作成します。
- nano src/Nav/Nav.css
ナビゲーションコンポーネントのスタイルは次のとおりです。
nav {
display: flex;
justify-content: center;
height: 50px;
margin-bottom: 10px;
}
nav > img {
display: block;
width: 50px;
height: auto;
}
それでは、App.js
ファイルを変更して、Nav
コンポーネントをレンダリングしてみましょう。
- nano src/App.js
Nav
コンポーネントをインポートし、App
コンポーネントで使用します。
import React, { Component } from 'react';
import Nav from './Nav';
class App extends Component {
render() {
return (
<div>
<Nav />
</div>
);
}
}
export default App;
これで、Webブラウザーでアプリを開くと、追加したロゴが表示されます。
ステップ4—UsersCard
コンポーネントを作成する
ユーザーカードは、ユーザーの詳細を表示する責任があります。 avatar
、name
、username
などの情報が含まれます。 followers
、following
、repos
も表示されます。
アプリのsrc
ディレクトリに、新しいUsers
ディレクトリを作成します。
- mkdir src/Users
次に、このディレクトリにUsersCard.js
ファイルを作成します。
- nano src/Users/UsersCard.js
そして、次のコードを追加します。
import React from 'react';
import { Link } from 'react-router-dom';
import './UsersCard.css'
const UsersCard = ({ user, match }) => <Link to={`${match.url}/${user.id}`} className="column card">
<img src={user.avatar} alt=""/>
<p className="users-card__name">{user.name}</p>
<p className="users-card__username">@{user.username}</p>
<div className="users-card__divider"></div>
<div className="users-card__stats">
<div>
<p>{user.followers}</p>
<span>Followers</span>
</div>
<div>
<p>{user.following}</p>
<span>Following</span>
</div>
<div>
<p>{user.repos}</p>
<span>Repositories</span>
</div>
</div>
</Link>;
export default UsersCard;
react-router-dom
のLink
コンポーネントは、カードがクリックされたときにユーザーが1人のユーザーの詳細を表示するためにナビゲートできるようにするために使用されます。
たとえば、UsersCard
のid
が10009
の場合、Link
コンポーネントは次のようなURLを生成します。
localhost:3000/10009
localhost:3000
は現在のURLを表します。10009
は$user.id
を表します。
このすべての情報は、コンポーネントがレンダリングされるときに渡されます。
次に、このディレクトリにUsersCard.css
ファイルを作成します。
- nano src/users/UsersCard.css
UsersCard
コンポーネントのスタイルは次のとおりです。
.card {
border-radius: 2px;
background-color: #ffffff;
box-shadow: 0 1.5px 3px 0 rgba(0, 0, 0, 0.05);
max-width: 228px;
margin: 10px;
display: flex;
flex-direction: column;
align-items: center;
padding: 0;
}
.card img {
width: 50px;
height: auto;
border-radius: 50%;
display: block;
padding: 15px 0;
}
.users-card__name {
font-weight: 400;
font-size: 16.5px;
line-height: 1.19;
letter-spacing: normal;
text-align: left;
color: #25292e;
}
.users-card__username {
font-size: 14px;
color: #707070;
}
.users-card__divider {
border: solid 0.5px #efefef;
width: 100%;
margin: 15px 0;
}
.users-card__stats {
display: flex;
}
.users-card__stats p {
font-size: 20px;
}
.users-card__stats div {
margin: 10px;
text-align: center;
}
.users-card__stats span {
color: #707070;
font-size: 12px;
}
この時点で、UsersCard
コンポーネントがあります。 次に、これらのカードをリストに表示する必要があります。
ステップ5—UsersList
コンポーネントを作成する
アプリケーションでユーザーを一覧表示するには、最初にUsersList
コンポーネントを作成する必要があります。
UsersCard.js
ファイルをsrc/Users
ディレクトリに作成します。
- nano UsersList.js
UsersList.js
を次のように編集してみましょう。
まず、必要なインポートを行います。
import React from 'react';
import UsersCard from './UsersCard';
import './UsersList.css';
users
の配列内の位置と一致するUsersCard
を構築するlistOfUsersPerRow
関数を定義します。
// ...
const listOfUsersPerRow = (users, row, itemsPerRow, match) =>
users
.slice((row - 1) * itemsPerRow, row * itemsPerRow)
.map(user => <UsersCard user={user} key={user.id} match={match} />);
itemsPerRow
の量で定義されたUsersCard
を含む"columns"
を構築するlistOfRows
関数を定義します。
// ...
const listOfRows = (users, itemsPerRow, match) => {
const numberOfUsers = users.length;
const rows = Math.ceil(numberOfUsers / itemsPerRow);
return Array(rows)
.fill()
.map((val, rowIndex) => (
<div className="columns">
{listOfUsersPerRow(users, rowIndex + 1, itemsPerRow, match)}
</div>
));
};
listOfUsersPerRow
およびlistOfRows
関数は、各行に指定された数以下のカードがあることを保証します。
次に、関数を使用してUsersList
を作成します。
//...
const UsersList = ({ users, itemsPerRow = 2, match }) => (
<div className="cards">
<h3 className="is-size-3 has-text-centered">Users</h3>
{listOfRows(users, itemsPerRow, match)}
</div>
);
export default UsersList;
次に、このディレクトリにUsersList.css
ファイルを作成します。
- nano src/Users/UsersList.css
UsersList
コンポーネントのスタイルは次のとおりです。
.cards {
margin-left: 20px;
}
.columns {
margin-top: 0;
}
この時点で、UsersCard
で構成されるUsersList
コンポーネントがあります。 次に、個々のユーザーの詳細ビューが必要になります。
ステップ6—UsersDetails
コンポーネントを作成する
UsersList
からシングルUsersCard
をクリックすると、詳細セクションの下にシングルUsersCard
が表示されます。
UsersDetails.js
ファイルをsrc/Users
ディレクトリに作成します。
- nano UsersDetails.js
そして、次のコードを追加します。
import React from 'react';
import UsersCard from './UsersCard';
const UsersDetails = ({ user, match }) => <div>
<h3 className="is-size-3 has-text-centered">Details</h3>
<UsersCard user={user} match={match} />
</div>;
export default UsersDetails;
この時点で、UsersDetails
コンポーネントがあります。 次に、UsersLists
とUsersDetails
を表示します。
ステップ7—UsersDashboard
コンポーネントの作成
ダッシュボードコンポーネントを作成するには、UsersList
を表示し、UsersCard
をクリックすると、ページをリロードせずに画面の横にUsersDetails
を表示します。
UsersDashboard.js
ファイルをsrc/Users
ディレクトリに作成します。
- nano src/Users/UsersDashboard.js
そして、次のコードを追加します。
import React from 'react';
import { Route } from 'react-router-dom';
import UsersList from './UsersList';
import UsersDetails from './UsersDetails';
const UsersDashboard = ({ users, user, match }) => (
<div className="columns">
<div className="column">
<UsersList users={users} match={match} />
</div>
<div className="column">
<Route
path={match.url + '/:id'}
render={props => (
<UsersDetails
user={
users.filter(
user => user.id === parseInt(props.match.params.id, 10)
)[0]
}
match={match}
/>
)}
/>
</div>
</div>
);
export default UsersDashboard;
このスニペットでは、react-router-dom
が提供するRoute
コンポーネントをコンポーネントとして使用して、カードがクリックされたときに特定のユーザーの詳細を表示しました。
この時点で、アプリケーションのすべてのコンポーネントが揃っています。
ステップ8—すべてをまとめる
それでは、これをすべてまとめましょう。
App.js
ファイルに再度アクセスしてください。
- nano src/App.js
Redirect
とUsersDashboard
を追加します。
import React, { Component } from 'react';
import { Route, Redirect } from 'react-router-dom';
import Nav from './Nav';
import UsersDashboard from './Users/UsersDashboard';
import './App.css';
users
の配列を含むstate
を追加します。
//...
class App extends Component {
state = {
users: [
{
id: 39191,
avatar: 'https://avatars0.githubusercontent.com/u/39191?v=4',
name: 'Paul Irish',
username: 'paulirish',
followers: '12k',
following: '1k',
repos: '1.5k'
},
// ... other user data
]
};
// ...
}
// ...
Route
とUsersDashboard
をApp
コンポーネントに追加します。
class App extends Component {
// ...
render() {
return (
<div className="App">
<Nav />
<Route
path="/dashboard"
render={props => (
<UsersDashboard users={this.state.users} {...props} />
)}
/>
<Redirect from="/" to="/dashboard"/>
<Redirect from="/users" to="/dashboard"/>
</div>
);
}
}
// ...
これで、アプリケーションをWebブラウザーで表示すると、UsersList
が表示されるはずです。 UsersCard
をクリックすると、UsersDetails
に表示されます。
ステップ9—レスポンシブルーティングの設定
ユーザーがこのアプリケーションにアクセスすると、画面サイズに関係なく、これと同じビューと機能が得られます。 本格的なアプリケーションでは、ユーザーが適切に楽しめるエクスペリエンスを提供することをお勧めします。 そのための1つの方法は、デバイスの正確なサイズに一致するビューを提供することです。 これをアプリケーションに実装します。
ワイドスクリーンでアプリケーションにアクセスすると、ユーザーはアプリケーションの/dashboard
ルートにリダイレクトされ、小さい画面で表示すると、ユーザーは/users
ルートにリダイレクトされます。応用。
src/App.js
ファイルを次のように更新します。
import React, { Component } from 'react';
import { Route, Switch, Redirect } from 'react-router-dom'; // add Switch
import Media from 'react-media'; // add Media
import Nav from './Nav';
import UsersList from './Users/UsersList'; // add UsersList
import UsersDetails from './Users/UsersDetails'; // add UsersDetails
import UsersDashboard from './Users/UsersDashboard';
import './App.css';
class App extends Component {
// ...
render() {
return (
<div className="App">
<Nav />
<Media query="(max-width: 599px)">
{matches =>
matches ? (
<Switch>
<Route
exact
path="/users"
render={props => (
<UsersList users={this.state.users} {...props} />
)}
/>
<Route
path="/users/:id"
render={props => (
<UsersDetails
user={
this.state.users.filter(
user =>
user.id === parseInt(props.match.params.id, 10)
)[0]
}
{...props}
/>
)}
/>
<Redirect from="/" to="/users"/>
<Redirect from="/dashboard" to="/users"/>
</Switch>
) : (
<Switch>
<Route
path="/dashboard"
render={props => (
<UsersDashboard users={this.state.users} {...props} />
)}
/>
<Redirect from="/" to="/dashboard"/>
<Redirect from="/users" to="/dashboard"/>
</Switch>
)
}
</Media>
</div>
);
}
}
export default App;
このスニペットでは、Media
コンポーネントを使用して画面のサイズを確認しました。 画面幅が599px
未満の場合は、さまざまなルートに表示する内容を設定し、/
および/dashboard
ルートを/users
にリダイレクトします。 ]ルート。
画面サイズが599px
より大きい場合は、前の手順で設定した完全なユーザーダッシュボードを表示します。
アプリケーションを実行します。
npm start
アプリケーションと対話し、画面サイズを調整して、アプリケーションと対話するときにルートがどのように異なる方法で処理されるかを確認します。
画面サイズに基づいてさまざまなルートを提供すると、メディアクエリを超えた何かが提供されます。これは、デバイスサイズに基づいて特別に設計されたコンポーネントをユーザーに提供できるようになったためです。
結論
この記事では、Reactを使用したコンポーネントベースのルーティングと、Reactアプリケーションに条件付きレンダリングを実装する方法を紹介しました。
このチュートリアルの完全なコードサンプルについては、GitHubのresponse-routingリポジトリを確認してください。
Reactの詳細については、 React.js シリーズのコーディング方法をご覧になるか、Reactトピックページで演習やプログラミングプロジェクトを確認してください。