介绍
在 React 中,响应式路由涉及根据设备的视图端口向用户提供不同的路由。CSS 媒体查询通常用于实现这一目标,但这限制了您使用 CSS 代理来显示或不显示不同的元素。
在本教程中,我们将向您展示如何在您的 React 应用程序中实施路由和服务响应路线. 通过遵循本教程,您将构建一个用户仪表板应用程序,根据设备屏幕的大小为用户提供不同的路线。
前提条件
要完成本教程,您将需要:
- Node.js 是本地安装的,您可以按照 如何安装 Node.js 和创建本地开发环境进行操作。
本教程已通过 Node 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 应用程序:
1npx create-react-app responsive-routing
然后,导航到新项目目录:
1cd responsive-routing
接下来,安装必要的模块,你将需要成功构建这个演示文稿. 这些模块是反应路由器-dom
和反应媒体
。
1npm install [email protected] [email protected]
现在,您可以通过运行命令启动应用程序:
1npm start
<$>[注] **注:**虽然不需要路由,但本教程使用了 Bulma CSS 框架来设计和布局。
您可以使用以下终端命令添加 Bulma:
1npm install [email protected]
并将以下内容添加到您的index.js
:
1[label index.js]
2import 'bulma/css/bulma.css';
美元
在此步骤中,您已经设置了您的项目,并添加了Bulma框架来设计和布局。
步骤 2 – 添加 React Router
要将路由添加到您的项目中,您需要修改您的 index.js 文件以使路由器位于元素等级的根基:
1nano index.js
首先,从react-router-dom
导入BrowserRouter
,并将其命名为Router
:
1[label index.js]
2import React from 'react';
3import ReactDOM from 'react-dom';
4import { BrowserRouter as Router } from "react-router-dom";
5import './index.css';
6import App from './App';
7import registerServiceWorker from './registerServiceWorker';
然后,用React
代替Router
:
1[label index.js]
2ReactDOM.render(
3 <Router>
4 <App />
5 </Router>,
6 document.getElementById('root')
7);
您的应用程序现在已设置为使用 React Router。
步骤 3 – 创建Nav
组件
页面中心的GitHub标志将作为您的应用程序的导航部分。
在您的src
目录中,创建一个名为Nav
的新目录:
1mkdir src/Nav
您需要添加 GitHub 标志并将其保存为logo.svg
在此目录中。
接下来,在这个目录中创建一个index.js
文件:
1nano src/Nav/index.js
然后添加以下代码:
1[label src/Nav/index.js]
2import React from 'react';
3import './Nav.css';
4import logo from './logo.svg';
5
6const Nav = () => (
7 <nav>
8 <img src={logo} alt="Logo" />
9 </nav>
10);
11
12export default Nav;
接下来,在这个目录中创建一个Nav.css
文件:
1nano src/Nav/Nav.css
导航组件具有以下风格:
1[label src/Nav/Nav.css]
2nav {
3 display: flex;
4 justify-content: center;
5 height: 50px;
6 margin-bottom: 10px;
7}
8
9nav > img {
10 display: block;
11 width: 50px;
12 height: auto;
13}
现在,让我们通过修改App.js
文件来渲染Nav
组件。
1nano src/App.js
导入Nav
组件并在您的应用
组件中使用它:
1[label src/App.js]
2import React, { Component } from 'react';
3import Nav from './Nav';
4
5class App extends Component {
6 render() {
7 return (
8 <div>
9 <Nav />
10 </div>
11 );
12 }
13}
14
15export default App;
现在,当您在 Web 浏览器中打开应用时,您应该看到您添加的标志。
步骤 4 – 创建用户卡
组件
用户卡将负责显示用户的详细信息,它将包含avatar
、name
和username
等信息,还会显示followers
,followers
和repos
。
在您的应用程序的src
目录中,创建一个新的用户
目录:
1mkdir src/Users
接下来,在这个目录中创建一个UsersCard.js
文件:
1nano src/Users/UsersCard.js
然后添加以下代码:
1[label src/Users/UsersCard.js]
2import React from 'react';
3import { Link } from 'react-router-dom';
4import './UsersCard.css'
5
6const UsersCard = ({ user, match }) => <Link to={`${match.url}/${user.id}`} className="column card">
7 <img src={user.avatar} alt=""/>
8 <p className="users-card__name">{user.name}</p>
9 <p className="users-card__username">@{user.username}</p>
10 <div className="users-card__divider"></div>
11 <div className="users-card__stats">
12 <div>
13 <p>{user.followers}</p>
14 <span>Followers</span>
15 </div>
16 <div>
17 <p>{user.following}</p>
18 <span>Following</span>
19 </div>
20 <div>
21 <p>{user.repos}</p>
22 <span>Repositories</span>
23 </div>
24 </div>
25</Link>;
26
27export default UsersCard;
从react-router-dom
中使用的链接
组件允许用户在点击卡时导航,查看单个用户的详细信息。
例如,如果一个用户卡
有一个ID
的10009
,则链接
组件将生成这样的URL:
1localhost:3000/10009
localhost:3000
表示当前的 URL.10009
表示 $user.id.
所有这些信息将在组件渲染时传递。
接下来,在这个目录中创建一个UsersCard.css
文件:
1nano src/users/UsersCard.css
UsersCard
组件具有以下风格:
1[label src/Users/UsersCard.css]
2.card {
3 border-radius: 2px;
4 background-color: #ffffff;
5 box-shadow: 0 1.5px 3px 0 rgba(0, 0, 0, 0.05);
6 max-width: 228px;
7 margin: 10px;
8 display: flex;
9 flex-direction: column;
10 align-items: center;
11 padding: 0;
12}
13
14.card img {
15 width: 50px;
16 height: auto;
17 border-radius: 50%;
18 display: block;
19 padding: 15px 0;
20}
21
22.users-card__name {
23 font-weight: 400;
24 font-size: 16.5px;
25 line-height: 1.19;
26 letter-spacing: normal;
27 text-align: left;
28 color: #25292e;
29}
30
31.users-card__username {
32 font-size: 14px;
33 color: #707070;
34}
35
36.users-card__divider {
37 border: solid 0.5px #efefef;
38 width: 100%;
39 margin: 15px 0;
40}
41
42.users-card__stats {
43 display: flex;
44}
45
46.users-card__stats p {
47 font-size: 20px;
48}
49
50.users-card__stats div {
51 margin: 10px;
52 text-align: center;
53}
54
55.users-card__stats span {
56 color: #707070;
57 font-size: 12px;
58}
在这一点上,你有一个UsersCard
组件,接下来,你需要在列表中显示这些卡片。
步骤 5 – 创建用户列表
组件
要让您的应用程序列出用户,您需要先创建一个用户列表
组件。
在src/Users
目录中创建一个UsersCard.js
文件:
1nano UsersList.js
让我们以以下方式编辑UsersList.js
。
首先,你会做必要的进口:
1[label src/Users/UsersList.js]
2import React from 'react';
3import UsersCard from './UsersCard';
4import './UsersList.css';
定义一个listOfUsersPerRow
函数,将构建一个UsersCard
,匹配其在用户
系列中的位置:
1// ...
2
3const listOfUsersPerRow = (users, row, itemsPerRow, match) =>
4 users
5 .slice((row - 1) * itemsPerRow, row * itemsPerRow)
6 .map(user => <UsersCard user={user} key={user.id} match={match} />);
定义一个listOfRows
函数,将构建包含UsersCard
的``列,定义为
itemsPerRow`的数量:
1// ...
2
3const listOfRows = (users, itemsPerRow, match) => {
4 const numberOfUsers = users.length;
5 const rows = Math.ceil(numberOfUsers / itemsPerRow);
6
7 return Array(rows)
8 .fill()
9 .map((val, rowIndex) => (
10 <div className="columns">
11 {listOfUsersPerRow(users, rowIndex + 1, itemsPerRow, match)}
12 </div>
13 ));
14};
listOfUsersPerRow
和listOfRows
功能确保每个行上没有超过指定的卡片数。
然后,使用这些函数创建一个用户列表
:
1[label src/Users/UsersList.js]
2//...
3
4const UsersList = ({ users, itemsPerRow = 2, match }) => (
5 <div className="cards">
6 <h3 className="is-size-3 has-text-centered">Users</h3>
7 {listOfRows(users, itemsPerRow, match)}
8 </div>
9);
10
11export default UsersList;
接下来,在这个目录中创建一个UsersList.css
文件:
1nano src/Users/UsersList.css
UsersList
组件具有以下风格:
1[label src/Users/UsersList.css]
2.cards {
3 margin-left: 20px;
4}
5
6.columns {
7 margin-top: 0;
8}
在此时,你有一个由UsersCard
组成的UsersList
组件,接下来,你需要一个个别用户的详细视图。
步骤 6 – 创建用户细节
组件
当单个用户卡
从用户列表
中点击时,单个用户卡
将在详细信息部分中显示。
在src/Users
目录中创建一个UsersDetails.js
文件:
1nano UsersDetails.js
然后添加以下代码:
1[label src/Users/UsersDetails.js]
2import React from 'react';
3import UsersCard from './UsersCard';
4
5const UsersDetails = ({ user, match }) => <div>
6 <h3 className="is-size-3 has-text-centered">Details</h3>
7 <UsersCard user={user} match={match} />
8 </div>;
9
10export default UsersDetails;
在此时,你有一个用户细节
组件,接下来,你会显示用户列表
和用户细节
。
步骤 7 — 创建用户Dashboard
组件
要创建仪表板组件,您将显示用户列表
,并在点击用户卡
时,在屏幕侧面显示用户详细信息
,而无需重新加载页面。
在src/Users
目录中创建一个UsersDashboard.js
文件:
1nano src/Users/UsersDashboard.js
然后添加以下代码:
1[label src/Users/UsersDashboard.js]
2import React from 'react';
3import { Route } from 'react-router-dom';
4import UsersList from './UsersList';
5import UsersDetails from './UsersDetails';
6
7const UsersDashboard = ({ users, user, match }) => (
8 <div className="columns">
9 <div className="column">
10 <UsersList users={users} match={match} />
11 </div>
12 <div className="column">
13 <Route
14 path={match.url + '/:id'}
15 render={props => (
16 <UsersDetails
17 user={
18 users.filter(
19 user => user.id === parseInt(props.match.params.id, 10)
20 )[0]
21 }
22 match={match}
23 />
24 )}
25 />
26 </div>
27 </div>
28);
29
30export default UsersDashboard;
在本片中,您使用了由react-router-dom
提供的Route
组件作为组件,在单击卡时显示特定用户细节。
此时此刻,您有您的应用程序的所有组件。
第8步:把一切都放在一起
现在,让我们把这一切放在一起。
查看App.js
文件:
1nano src/App.js
添加重定向
和用户面板
:
1[label src/App.js]
2import React, { Component } from 'react';
3import { Route, Redirect } from 'react-router-dom';
4import Nav from './Nav';
5import UsersDashboard from './Users/UsersDashboard';
6import './App.css';
添加包含一组用户
的状态
:
1[label src/App.js]
2//...
3
4class App extends Component {
5 state = {
6 users: [
7 {
8 id: 39191,
9 avatar: 'https://avatars0.githubusercontent.com/u/39191?v=4',
10 name: 'Paul Irish',
11 username: 'paulirish',
12 followers: '12k',
13 following: '1k',
14 repos: '1.5k'
15 },
16 // ... other user data
17 ]
18 };
19
20 // ...
21}
22
23// ...
将Route
和UsersDashboard
添加到您的App
组件中:
1class App extends Component {
2 // ...
3
4 render() {
5 return (
6 <div className="App">
7 <Nav />
8 <Route
9 path="/dashboard"
10 render={props => (
11 <UsersDashboard users={this.state.users} {...props} />
12 )}
13 />
14 <Redirect from="/" to="/dashboard"/>
15 <Redirect from="/users" to="/dashboard"/>
16 </div>
17 );
18 }
19}
20
21// ...
现在,当您在 Web 浏览器中查看您的应用程序时,您应该看到一个用户列表
。当您点击用户卡
,您将看到它显示在用户细节
。
第9步:设置响应式路由
当用户访问这个应用程序时,无论屏幕大小如何,他们都会得到相同的视图和功能。在全面的应用程序中,它是好的给用户体验,他们可以正确地享受。
在大屏幕上访问应用程序时,用户将被重定向到应用程序的/dashboard
路线,而在小屏幕上查看时,用户将被重定向到应用程序的/users
路线。
更新「src/App.js」檔案,看起來像這樣:
1[label src/App.js]
2import React, { Component } from 'react';
3import { Route, Switch, Redirect } from 'react-router-dom'; // add Switch
4import Media from 'react-media'; // add Media
5import Nav from './Nav';
6import UsersList from './Users/UsersList'; // add UsersList
7import UsersDetails from './Users/UsersDetails'; // add UsersDetails
8import UsersDashboard from './Users/UsersDashboard';
9import './App.css';
10
11class App extends Component {
12 // ...
13
14 render() {
15 return (
16 <div className="App">
17 <Nav />
18 <Media query="(max-width: 599px)">
19 {matches =>
20 matches ? (
21 <Switch>
22 <Route
23 exact
24 path="/users"
25 render={props => (
26 <UsersList users={this.state.users} {...props} />
27 )}
28 />
29 <Route
30 path="/users/:id"
31 render={props => (
32 <UsersDetails
33 user={
34 this.state.users.filter(
35 user =>
36 user.id === parseInt(props.match.params.id, 10)
37 )[0]
38 }
39 {...props}
40 />
41 )}
42 />
43 <Redirect from="/" to="/users"/>
44 <Redirect from="/dashboard" to="/users"/>
45 </Switch>
46 ) : (
47 <Switch>
48 <Route
49 path="/dashboard"
50 render={props => (
51 <UsersDashboard users={this.state.users} {...props} />
52 )}
53 />
54 <Redirect from="/" to="/dashboard"/>
55 <Redirect from="/users" to="/dashboard"/>
56 </Switch>
57 )
58 }
59 </Media>
60 </div>
61 );
62 }
63}
64
65export default App;
如果屏幕宽度小于599px
,你会为不同的路线设置要显示的内容,并将/
和/dashboard
路线重定向到/users
路线。
如果屏幕大小大于599px
,则如前一步所示,将显示完整的用户仪表板。
运行应用程序:
1npm start
与应用程序互动,并调整屏幕大小,以查看在与应用程序互动时如何不同地处理路线。
根据屏幕大小提供不同的路径提供超越媒体查询的功能,因为您现在可以根据设备大小为用户提供专门设计的组件。
结论
在本文中,您介绍了React的基于组件的路由以及如何在React应用程序中实施条件渲染。
对于本教程的完整代码样本,请查看 GitHub 上的 responsive-routing
存储库。
如果您想了解更多关于 React 的信息,请查看我们的 如何在 React.js 中编码系列,或查看 我们的 React 主题页面以获取练习和编程项目。