Cách thiết lập định tuyến có điều kiện và đáp ứng với React Router v4
Định tuyến đáp ứng trong React liên quan đến việc cung cấp các tuyến đường khác nhau cho user dựa trên khung nhìn của thiết bị của họ. Các media query CSS thường được sử dụng để đạt được điều này, nhưng điều này hạn chế bạn hiển thị hoặc không hiển thị các phần tử khác nhau bằng cách sử dụng các đạo cụ CSS. Với các tuyến đáp ứng, giờ đây bạn có thể phân phát toàn bộ các chế độ xem riêng biệt của các ứng dụng React của bạn cho những user khác nhau trực tiếp dựa trên kích thước màn hình của họ.Trong hướng dẫn này, ta sẽ chỉ cho bạn cách triển khai định tuyến và cung cấp các tuyến đáp ứng trong các ứng dụng React của bạn. Theo hướng dẫn này, bạn sẽ xây dựng một ứng dụng console user phục vụ các tuyến đường khác nhau cho user dựa trên kích thước màn hình thiết bị của họ.
Yêu cầu
Để hoàn thành hướng dẫn này, bạn cần :
- Node.js được cài đặt local mà bạn có thể thực hiện theo Cách cài đặt Node.js và Tạo Môi trường Phát triển Cục bộ .
Hướng dẫn này đã được xác minh với Node v14.2.0, npm
v6.14.5, react
v16.3.2, react-router-dom
v5.2.0, và react-media
v1.10.0.
Bước 1 - Cài đặt dự án
Để bắt đầu dự án của bạn, hãy sử dụng npx
và create-react-app
npx
create-react-app
để tạo một ứng dụng React mới:
- npx create-react-app responsive-routing
Sau đó, chuyển đến folder dự án mới:
- cd responsive-routing
Tiếp theo, cài đặt các module cần thiết bạn cần để xây dựng thành công bản demo này. Các module này là react-router-dom
và react-media
. Bạn có thể cài đặt chúng bằng cách chạy lệnh:
- npm install react-router-dom@5.2.0 react-media@1.10.0
Bây giờ, bạn có thể khởi động ứng dụng bằng cách chạy lệnh:
- npm start
Lưu ý: Mặc dù không bắt buộc đối với việc định tuyến, nhưng hướng dẫn này sử dụng khung CSS Bulma để tạo kiểu và bố cục.
Bạn có thể thêm Bulma bằng lệnh terminal sau:
- npm install bulma@0.6.2
Và bằng cách thêm phần sau vào index.js
của bạn:
import 'bulma/css/bulma.css';
Trong bước này, bạn đã cài đặt dự án của bạn và thêm khung Bulma để tạo kiểu và bố cục.
Bước 2 - Thêm Bộ định tuyến React
Để thêm định tuyến vào dự án của bạn, bạn cần sửa đổi index.js
của bạn để hiển thị bộ định tuyến ở root của hệ thống phân cấp phần tử của bạn:
- nano index.js
Đầu tiên, nhập BrowserRouter
từ BrowserRouter
react-router-dom
và đặt alias là 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';
Sau đó, thay thế <React>
bằng <Router>
:
ReactDOM.render( <Router> <App /> </Router>, document.getElementById('root') );
Ứng dụng của bạn hiện đã được cài đặt để sử dụng React Router.
Bước 3 - Tạo Nav
Component
Biểu trưng GitHub ở giữa trang sẽ đóng role là phần chuyển của ứng dụng của bạn.
Trong folder src
của bạn, tạo một folder mới có tên là Nav
:
- mkdir src/Nav
Bạn cần thêm logo GitHub và lưu nó dưới dạng logo.svg
trong folder này.
Tiếp theo, tạo index.js
trong folder này:
- nano src/Nav/index.js
Và thêm mã sau:
import React from 'react'; import './Nav.css'; import logo from './logo.svg'; const Nav = () => ( <nav> <img src={logo} alt="Logo" /> </nav> ); export default Nav;
Tiếp theo, tạo file Nav.css
trong folder này:
- nano src/Nav/Nav.css
Thành phần chuyển có kiểu sau:
nav { display: flex; justify-content: center; height: 50px; margin-bottom: 10px; } nav > img { display: block; width: 50px; height: auto; }
Bây giờ, hãy kết xuất thành phần Nav
bằng cách sửa đổi file App.js
- nano src/App.js
Nhập Nav
thành phần và sử dụng nó trong của bạn App
thành phần:
import React, { Component } from 'react'; import Nav from './Nav'; class App extends Component { render() { return ( <div> <Nav /> </div> ); } } export default App;
Bây giờ, khi bạn mở ứng dụng của bạn trong trình duyệt web, bạn sẽ thấy biểu trưng bạn đã thêm.
Bước 4 - Tạo thành phần UsersCard
Thẻ user sẽ chịu trách nhiệm hiển thị thông tin chi tiết của user . Nó sẽ chứa thông tin như avatar
, name
và username
. Nó cũng sẽ hiển thị followers
, following
, và repos
.
Trong folder src
của ứng dụng, hãy tạo một folder Users
mới:
- mkdir src/Users
Tiếp theo, tạo file UsersCard.js
trong folder này:
- nano src/Users/UsersCard.js
Và thêm mã sau:
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;
Thành phần Link
từ react-router-dom
được sử dụng để cho phép user chuyển để xem chi tiết của một user khi thẻ được nhấp vào.
Ví dụ: nếu UsersCard
có id
là 10009
, thành phần Link
sẽ tạo một URL như sau:
localhost:3000/10009
localhost:3000
đại diện cho URL hiện tại.-
10009
đại diện cho$user.id
Tất cả thông tin này sẽ được chuyển khi thành phần được hiển thị.
Tiếp theo, tạo file UsersCard.css
trong folder này:
- nano src/users/UsersCard.css
Thành phần UsersCard
có kiểu sau:
.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; }
Đến đây, bạn có một thành phần UsersCard
. Tiếp theo, bạn cần hiển thị các thẻ chủ đề trong một danh sách.
Bước 5 - Tạo thành phần UsersList
Để đưa ứng dụng của bạn vào danh sách user , trước tiên bạn cần tạo một thành phần UsersList
.
Tạo file UsersCard.js
trong folder src/Users
:
- nano UsersList.js
Hãy chỉnh sửa UsersList.js
như sau.
Đầu tiên, bạn sẽ thực hiện các lần nhập cần thiết:
import React from 'react'; import UsersCard from './UsersCard'; import './UsersList.css';
Xác định một hàm listOfUsersPerRow
sẽ tạo ra một UsersCard
trùng với vị trí của họ trong mảng users
:
// ... const listOfUsersPerRow = (users, row, itemsPerRow, match) => users .slice((row - 1) * itemsPerRow, row * itemsPerRow) .map(user => <UsersCard user={user} key={user.id} match={match} />);
Xác định một hàm listOfRows
sẽ tạo ra các "columns"
có chứa UsersCard
được xác định bởi số lượng itemsPerRow
:
// ... 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> )); };
Các listOfUsersPerRow
và listOfRows
đảm bảo bạn có không nhiều hơn số thẻ được chỉ định trên mỗi hàng.
Sau đó, sử dụng các chức năng để tạo 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;
Tiếp theo, tạo file UsersList.css
trong folder này:
- nano src/Users/UsersList.css
Thành phần UsersList
có kiểu sau:
.cards { margin-left: 20px; } .columns { margin-top: 0; }
Đến đây, bạn có một thành phần UsersList
bao gồm các UsersCard
. Tiếp theo, bạn cần một cái nhìn chi tiết cho một user cá nhân.
Bước 6 - Tạo thành phần UsersDetails
Khi một đơn UsersCard
được nhấp từ UsersList
, single UsersCard
được hiển thị dưới phần chi tiết.
Tạo file UsersDetails.js
trong folder src/Users
:
- nano UsersDetails.js
Và thêm mã sau:
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;
Đến đây, bạn có một thành phần UsersDetails
. Tiếp theo, bạn sẽ hiển thị UsersLists
và UsersDetails
.
Bước 7 - Tạo thành phần UsersDashboard
Để tạo thành phần console , bạn sẽ hiển thị Danh sách người UsersList
và khi một UsersCard
được nhấp vào, hiển thị UsersDetails
user ở bên cạnh màn hình mà không cần phải reload trang.
Tạo file UsersDashboard.js
trong folder src/Users
:
- nano src/Users/UsersDashboard.js
Và thêm mã sau:
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;
Trong đoạn mã này, bạn đã sử dụng thành phần Route
được cung cấp bởi react-router-dom
làm thành phần để hiển thị chi tiết user cụ thể khi thẻ được nhấp vào.
Đến đây, bạn có tất cả các thành phần cho ứng dụng của bạn .
Bước 8 - Kết hợp tất cả lại với nhau
Bây giờ, hãy tập hợp tất cả lại với nhau.
Xem lại file App.js
:
- nano src/App.js
Thêm Redirect
và 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';
Thêm state
chứa một mảng users
:
//... 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 ] }; // ... } // ...
Thêm Route
và UsersDashboard
vào thành phần App
của bạn:
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> ); } } // ...
Bây giờ, khi xem ứng dụng của bạn trong trình duyệt web, bạn sẽ thấy UsersList
. Khi nhấp vào UsersCard
, bạn sẽ thấy nó hiển thị trong UsersDetails
.
Bước 9 - Cài đặt định tuyến đáp ứng
Khi user truy cập ứng dụng này, dù kích thước màn hình, họ đều có được chế độ xem và chức năng giống nhau. Trong các ứng dụng toàn diện, thật tốt khi mang đến cho user những trải nghiệm mà họ có thể tận hưởng đúng cách. Một cách để làm điều đó là cung cấp cho họ những lượt xem phù hợp với kích thước thiết bị chính xác của họ. Đến đây bạn sẽ thực hiện điều này trong ứng dụng của bạn .
Khi truy cập ứng dụng trên màn hình rộng, user được chuyển hướng đến tuyến /dashboard
của ứng dụng và khi xem trên màn hình nhỏ hơn, user sẽ được chuyển hướng đến tuyến /users
của ứng dụng.
Cập nhật file src/App.js
trông giống như sau:
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;
Trong đoạn mã này, bạn đã sử dụng thành phần Media
để kiểm tra kích thước của màn hình. Nếu chiều rộng màn hình nhỏ hơn 599px
, bạn đặt những gì bạn muốn được hiển thị cho các tuyến đường khác nhau và cũng chuyển hướng các tuyến đường /
và /dashboard
đến tuyến đường /users
.
Nếu kích thước màn hình lớn hơn 599px
, bạn sẽ hiển thị trang tổng quan user đầy đủ như đã cài đặt ở bước trước.
Chạy ứng dụng:
npm start
Tương tác với ứng dụng của bạn và điều chỉnh kích thước màn hình của bạn để xem các tuyến đường được xử lý khác nhau như thế nào khi tương tác với ứng dụng.
Việc phân phát các tuyến đường khác nhau dựa trên kích thước màn hình mang lại điều gì đó ngoài các media query , vì giờ đây bạn có thể phân phối các thành phần được thiết kế đặc biệt cho user dựa trên kích thước thiết bị của họ.
Kết luận
Trong bài viết này, bạn đã được giới thiệu về định tuyến dựa trên thành phần với React và cách triển khai kết xuất có điều kiện trong các ứng dụng React của bạn.
Để có mẫu mã hoàn chỉnh của hướng dẫn này, hãy xem repository responsive-routing
trên GitHub.
Nếu bạn muốn tìm hiểu thêm về React, hãy xem loạt bài Cách viết mã trong React.js của ta hoặc xem trang chủ đề React của ta để biết các bài tập và dự án lập trình.
Các tin liên quan