Cách xử lý định tuyến trong ứng dụng React với React Router
Trong React , bộ định tuyến giúp tạo và chuyển giữa các URL khác nhau tạo nên ứng dụng web của bạn. Chúng cho phép user của bạn di chuyển giữa cácthành phần của ứng dụng trong khi vẫn duy trì trạng thái user và có thể cung cấp các URL duy nhất cho các thành phần này để giúp chúng dễ chia sẻ hơn. Với bộ định tuyến, bạn có thể cải thiện trải nghiệm user của ứng dụng bằng cách đơn giản hóa việc chuyển trang web.React Router là một trong những khung định tuyến phổ biến nhất cho React. Thư viện được thiết kế với các thành phần trực quan để cho phép bạn xây dựng một hệ thống định tuyến khai báo cho ứng dụng của bạn . Điều này nghĩa là bạn có thể khai báo chính xác thành phần nào của bạn có một tuyến đường nhất định. Với định tuyến khai báo, bạn có thể tạo các tuyến trực quan mà con người có thể đọc được, giúp quản lý kiến trúc ứng dụng của bạn dễ dàng hơn.
Trong hướng dẫn này, bạn sẽ cài đặt và cấu hình Bộ định tuyến React, xây dựng một tập hợp các tuyến và kết nối với chúng bằng thành phần <Link>
. Bạn cũng sẽ xây dựng các tuyến động thu thập dữ liệu từ một URL mà bạn có thể truy cập trong thành phần của bạn . Cuối cùng, bạn sẽ sử dụng Hooks để truy cập dữ liệu và thông tin định tuyến khác và tạo các tuyến lồng nhau sống bên trong các thành phần được các tuyến mẹ hiển thị.
Đến cuối hướng dẫn này, bạn có thể thêm các tuyến vào bất kỳ dự án React nào và đọc thông tin từ các tuyến của bạn để bạn có thể tạo các thành phần linh hoạt phản hồi dữ liệu URL.
Yêu cầu
Bạn cần một môi trường phát triển chạy Node.js ; hướng dẫn này đã được thử nghiệm trên Node.js version 10.22.0 và npm version 6.14.6. Để cài đặt phần mềm này trên macOS hoặc Ubuntu 18.04, hãy làm theo các bước trong Cách cài đặt Node.js và Tạo Môi trường Phát triển Cục bộ trên macOS hoặc phần Cài đặt Sử dụng PPA của Cách Cài đặt Node.js trên Ubuntu 18.04 .
Môi trường phát triển React được cài đặt với Create React App , với phần trình bày không cần thiết bị xóa. Để cài đặt điều này, hãy làm theo Bước 1 - Tạo một dự án trống của hướng dẫn Cách quản lý trạng thái trên các thành phần lớp React . Hướng dẫn này sẽ sử dụng
router-tutorial
làm tên dự án.Bạn sẽ sử dụng các thành phần React và các Hook tùy chỉnh trong suốt hướng dẫn. Bạn có thể tìm hiểu về các thành phần trongCách tạo các thành phần tùy chỉnh trong React và Hooks trong Cách quản lý trạng thái với Hooks trên các thành phần React .
Bạn cũng cần kiến thức cơ bản về JavaScript, HTML và CSS, bạn có thể tìm thấy kiến thức này trong loạt bài Cách tạo trang web bằng HTML , loạt bài Cách tạo trang web bằng CSS và trong loạt bài Cách viết mã bằng JavaScript .
Bước 1 - Cài đặt Bộ định tuyến React
Trong bước này, bạn sẽ cài đặt React Router vào dự án cơ sở của bạn . Trong dự án này, bạn sẽ tạo một trang web nhỏ về các loài động vật có vú ở biển. Mỗi động vật có vú cần một thành phần riêng biệt mà bạn sẽ kết xuất với bộ định tuyến. Sau khi cài đặt thư viện, bạn sẽ tạo một loạt các thành phần cho mỗi động vật có vú.Đến cuối bước này, bạn sẽ có nền tảng để vẽ các loài động vật có vú khác nhau dựa trên tuyến đường.
Để bắt đầu, hãy cài đặt gói React Router. Có hai version khác nhau: version web và version root để sử dụng với React Native . Bạn sẽ cài đặt version web.
Trong terminal của bạn, sử dụng npm
để cài đặt gói:
- npm install react-router-dom
Gói sẽ cài đặt và bạn sẽ nhận được một thông báo như thông báo này khi quá trình cài đặt hoàn tất. Thông điệp của bạn có thể hơi khác một chút:
Output... + react-router-dom@5.2.0 added 11 packages from 6 contributors and audited 1981 packages in 24.897s 114 packages are looking for funding run `npm fund` for details found 0 vulnerabilities
Đến đây bạn đã cài đặt gói. Trong phần còn lại của bước này, bạn sẽ tạo một loạt các thành phần mà mỗi thành phần sẽ có một tuyến duy nhất.
Để bắt đầu, hãy tạo một folder cho ba loài động vật có vú khác nhau: lợn biển, kỳ lân biển và cá voi. Chạy các lệnh sau:
- mkdir src/components/Manatee
- mkdir src/components/Narwhal
- mkdir src/components/Whale
Tiếp theo, tạo một thành phần cho mỗi con vật. Thêm <h2>
cho mỗi động vật có vú. Trong một ứng dụng đầy đủ, các thành phần con có thể phức tạp như bạn muốn. Họ thậm chí có thể nhập và hiển thị các thành phần con của riêng họ. Đối với hướng dẫn này, bạn sẽ chỉ hiển thị <h2>
.
Bắt đầu với thành phần lợn biển. Mở Manatee.js
trong editor của bạn:
- nano src/components/Manatee/Manatee.js
Sau đó thêm thành phần cơ bản:
import React from 'react'; export default function Manatee() { return <h2>Manatee</h2>; }
Lưu và đóng file .
Tiếp theo, tạo một thành phần cho kỳ lân biển:
- nano src/components/Narwhal/Narwhal.js
Thêm thành phần cơ bản tương tự, thay đổi <h2>
thành Kỳ Narwhal
:
import React from 'react'; export default function Narwhal() { return <h2>Narwhal</h2>; }
Lưu và đóng file .
Cuối cùng, tạo một file cho Whale
:
- nano src/components/Whale/Whale.js
Thêm thành phần cơ bản tương tự, thay đổi <h2>
thành Whale
:
import React from 'react'; export default function Whale() { return <h2>Whale</h2>; }
Lưu và đóng file . Trong bước tiếp theo, bạn sẽ bắt đầu kết nối các tuyến đường; bây giờ, hãy hiển thị thành phần cơ bản trong ứng dụng của bạn.
Mở App.js
:
- nano src/components/App/App.js
Thêm <h1>
với tên của trang web ( Marine Mammals
) bên trong <div>
với className
của wrapper
. Điều này sẽ phục vụ như một mẫu. Shell bọc và <h1>
sẽ hiển thị trên mọi trang. Trong các ứng dụng đầy đủ, bạn có thể thêm thanh chuyển hoặc thành phần tiêu đề mà bạn muốn trên mọi trang.
Thêm các dòng được đánh dấu sau vào file :
import React from 'react'; import './App.css'; function App() { return ( <div className="wrapper"> <h1>Marine Mammals</h1> </div> ); } export default App;
Tiếp theo, nhập Manatee
và hiển thị bên trong <div>
. Điều này sẽ hoạt động như một trình giữ chỗ cho đến khi bạn thêm các tuyến đường khác:
import React from 'react'; import './App.css'; import Manatee from '../Manatee/Manatee'; function App() { return ( <div className="wrapper"> <h1>Marine Mammals</h1> <Manatee /> </div> ); } export default App;
Lưu và đóng file .
Đến đây bạn đã có tất cả các thành phần, hãy thêm một số đệm để cung cấp cho ứng dụng một ít không gian.
Mở App.css
:
- nano src/components/App/App.css
Sau đó, thay thế nội dung bằng đoạn mã sau để thêm phần padding
20px
vào lớp .wrapper
:
.wrapper { padding: 20px; }
Lưu và đóng file . Khi bạn làm như vậy, trình duyệt sẽ làm mới để hiển thị thành phần cơ bản của bạn:
Đến đây bạn có một thành phần root cơ bản mà bạn sẽ sử dụng để hiển thị các thành phần khác. Nếu bạn không có bộ định tuyến, bạn có thể hiển thị có điều kiện các thành phần bằng useState
Hook . Nhưng điều này sẽ không mang lại trải nghiệm tuyệt vời cho user của bạn. Khi nào user làm mới trang, lựa chọn của user sẽ không xuất hiện . Hơn nữa, họ sẽ không thể đánh dấu trang hoặc chia sẻ các trạng thái cụ thể của ứng dụng. Một bộ định tuyến sẽ giải quyết tất cả những vấn đề này. Bộ định tuyến sẽ duy trì trạng thái user và sẽ cung cấp cho user một URL rõ ràng để họ có thể lưu hoặc gửi cho người khác.
Trong bước này, bạn đã cài đặt React Router và tạo các thành phần cơ bản. Các thành phần sẽ là các trang riêng lẻ mà bạn sẽ hiển thị theo tuyến. Trong bước tiếp theo, bạn sẽ thêm các tuyến đường và sử dụng thành phần <Link>
để tạo các siêu liên kết hiệu quả.
Bước 2 - Thêm tuyến đường
Trong bước này, bạn sẽ tạo một bộ định tuyến cơ sở với các tuyến riêng cho từng trang. Bạn sẽ sắp xếp các tuyến của bạn đảm bảo rằng các thành phần được hiển thị chính xác và bạn sẽ sử dụng thành phần <Link>
để thêm các siêu liên kết vào dự án của bạn mà sẽ không kích hoạt làm mới trang.
Đến cuối bước này, bạn sẽ có một ứng dụng với chuyển sẽ hiển thị các thành phần của bạn theo tuyến đường.
React Router là một khung định tuyến khai báo. Điều đó nghĩa là bạn sẽ cấu hình các tuyến sử dụng các thành phần React tiêu chuẩn. Có một số lợi thế cho cách tiếp cận này. Đầu tiên, nó tuân theo bản chất giải mã tiêu chuẩn của mã React. Bạn không cần phải thêm nhiều mã trong componentDidMount
phương thức componentDidMount
hoặc bên trong useEffect
Hook; các tuyến đường của bạn là các thành phần. Thứ hai, bạn có thể đặt các tuyến đường bên trong một thành phần một cách trực quan với các thành phần khác đóng role như một mẫu. Khi bạn đọc mã, bạn sẽ tìm thấy chính xác nơi các thành phần động sẽ phù hợp với các chế độ xem toàn cục như chuyển hoặc chân trang.
Để bắt đầu thêm các tuyến đường, hãy mở App.js
:
- nano src/components/App/App.js
Thẻ <h1>
sẽ đóng role là tiêu đề trang global . Vì bạn muốn nó xuất hiện trên mọi trang, hãy cấu hình bộ định tuyến sau thẻ.
Nhập BrowserRouter
, Route
và Switch
từ BrowserRouter
react-router-dom
. BrowserRouter
sẽ là cấu hình cơ sở. Switch
sẽ bao bọc các tuyến đường động và thành phần Route
sẽ cấu hình các tuyến đường cụ thể và bọc thành phần sẽ hiển thị:
import React from 'react'; import { BrowserRouter, Route, Switch } from 'react-router-dom'; import './App.css'; import Manatee from '../Manatee/Manatee'; function App() { return ( <div className="wrapper"> <h1>Marine Mammals</h1> <Manatee /> </div> ); } export default App;
Thêm thành phần BrowserRouter
để tạo bộ định tuyến cơ sở. Mọi thứ bên ngoài thành phần này sẽ hiển thị trên mọi trang, vì vậy hãy đặt nó sau <h1>
của bạn. Ngoài ra, nếu bạn có context
toàn trang muốn sử dụng hoặc một số cửa hàng khác như Redux , hãy đặt các thành phần đó bên ngoài bộ định tuyến. Điều này sẽ cung cấp chúng cho tất cả các thành phần trên mọi tuyến đường:
import React from 'react'; import { BrowserRouter, Route, Switch } from 'react-router-dom'; import './App.css'; import Manatee from '../Manatee/Manatee'; function App() { return ( <div className="wrapper"> <h1>Marine Mammals</h1> <BrowserRouter> <Manatee /> </BrowserRouter> </div> ); } export default App;
Tiếp theo, thêm thành phần Switch
bên trong BrowserRouter
. Thành phần này sẽ kích hoạt đúng tuyến, giống như câu lệnh JavaScript switch
. Bên trong Switch
, thêm thành phần Route
cho mỗi tuyến đường. Trong trường hợp này, bạn cần các tuyến đường sau: /manataee
, /narwhal
và /whale
. Thành phần Route
sẽ lấy một path
làm tham số và bao quanh một thành phần con. Thành phần con sẽ hiển thị khi tuyến đường hoạt động.
Tạo một lộ trình cho đường dẫn /
và hiển thị thành phần Manatee
:
import React from 'react'; import { BrowserRouter, Route, Switch } from 'react-router-dom'; import './App.css'; import Manatee from '../Manatee/Manatee'; function App() { return ( <div className="wrapper"> <h1>Marine Mammals</h1> <BrowserRouter> <Switch> <Route path="/"> <Manatee /> </Route> </Switch> </BrowserRouter> </div> ); } export default App;
Lưu các file . Khi bạn thực hiện, trình duyệt sẽ reload và bạn sẽ tìm thấy thông tin cho thành phần lợn biển:
Nếu bạn thử một tuyến đường khác, chẳng hạn như http://localhost:3000/whale
, bạn sẽ vẫn tìm thấy thành phần lợn biển.
Thành phần Switch
sẽ hiển thị tuyến đường đầu tiên phù hợp với mẫu đó. Bất kỳ tuyến đường nào cũng sẽ khớp /
, vì vậy nó sẽ hiển thị trên mọi trang. Điều đó cũng nghĩa là thứ tự là quan trọng. Vì bộ định tuyến sẽ thoát ngay khi tìm thấy một điểm trùng khớp, nên luôn đặt một tuyến cụ thể hơn trước một tuyến ít cụ thể hơn. Nói cách khác, /whale
sẽ đi trước /
và /whale/beluga
sẽ đi trước /whale
.
Nếu bạn muốn tuyến đường chỉ trùng với tuyến đường như đã viết chứ không phải bất kỳ tuyến đường con nào, bạn có thể thêm phần hỗ trợ exact
. Ví dụ: <Route exact path="/manatee">
sẽ trùng với /manatee
, nhưng không trùng với /manatee/african
.
Cập nhật các tuyến đường cho Manatee
thành phần để /manatee
, sau đó nhập các thành phần còn lại và tạo ra một lộ trình cho từng:
import React from 'react'; import { BrowserRouter, Route, Switch } from 'react-router-dom'; import './App.css'; import Manatee from '../Manatee/Manatee'; import Narwhal from '../Narwhal/Narwhal'; import Whale from '../Whale/Whale'; function App() { return ( <div className="wrapper"> <h1>Marine Mammals</h1> <BrowserRouter> <Switch> <Route path="/manatee"> <Manatee /> </Route> <Route path="/narwhal"> <Narwhal /> </Route> <Route path="/whale"> <Whale /> </Route> </Switch> </BrowserRouter> </div> ); } export default App;
Lưu các file . Khi bạn làm như vậy, trình duyệt sẽ làm mới. Nếu bạn truy cập http://localhost:3000/
, chỉ <h1>
sẽ hiển thị, vì không có tuyến nào trùng với bất kỳ thành phần Route
:
Nếu bạn truy cập http://localhost:3000/whale
, bạn sẽ tìm thấy thành phần Whale
:
Đến đây bạn đã có một số thành phần, hãy tạo chuyển để user di chuyển giữa các trang.
Sử dụng phần tử <nav>
để biểu thị rằng bạn đang tạo một phần chuyển của trang. Sau đó, thêm một danh sách không có thứ tự ( <ul>
) với một mục danh sách ( <li>
) và một siêu liên kết ( <a>
) cho mỗi động vật có vú:
import React from 'react'; import { BrowserRouter, Route, Switch } from 'react-router-dom'; import './App.css'; import Manatee from '../Manatee/Manatee'; import Narwhal from '../Narwhal/Narwhal'; import Whale from '../Whale/Whale'; function App() { return ( <div className="wrapper"> <h1>Marine Mammals</h1> <nav> <ul> <li><a href="/manatee">Manatee</a></li> <li><a href="/narwhal">Narwhal</a></li> <li><a href="/whale">Whale</a></li> </ul> </nav> <BrowserRouter> ... </BrowserRouter> </div> ); } export default App;
Lưu các file . Khi bạn làm như vậy, trình duyệt sẽ làm mới, nhưng sẽ có sự cố. Vì bạn đang sử dụng các liên kết root của trình duyệt— thẻ <a>
— bạn sẽ nhận được hành vi mặc định của trình duyệt bất kỳ khi nào bạn nhấp vào một liên kết. Điều đó nghĩa là bất kỳ khi nào bạn nhấp vào một liên kết, bạn sẽ kích hoạt làm mới toàn bộ trang.
Lưu ý mạng sẽ reload tất cả các file JavaScript khi bạn nhấp vào một liên kết. Đó là một chi phí hiệu suất lớn cho user của bạn.
Đến đây, bạn có thể thêm trình xử lý sự kiện click
trên mỗi liên kết và ngăn hành động mặc định. Đó sẽ là rất nhiều công việc. Thay vào đó, React Router có một thành phần đặc biệt gọi là Link
sẽ xử lý công việc cho bạn. Nó sẽ tạo một thẻ liên kết, nhưng ngăn hành vi của trình duyệt mặc định trong khi đẩy vị trí mới.
Trong App.js
, nhập Link
từ App.js
react-router-dom
. Sau đó, thay thế mỗi <a>
bằng một Link
. Bạn cũng cần thay đổi thuộc tính href
thành to
prop.
Cuối cùng, di chuyển thành phần <nav>
vào bên trong BrowserRouter
. Điều này đảm bảo thành phần Link
được kiểm soát bởi react-router
:
import React from 'react'; import { BrowserRouter, Link, Route, Switch } from 'react-router-dom'; import './App.css'; import Manatee from '../Manatee/Manatee'; import Narwhal from '../Narwhal/Narwhal'; import Whale from '../Whale/Whale'; function App() { return ( <div className="wrapper"> <h1>Marine Mammals</h1> <BrowserRouter> <nav> <ul> <li><Link to="/manatee">Manatee</Link></li> <li><Link to="/narwhal">Narwhal</Link></li> <li><Link to="/whale">Whale</Link></li> </ul> </nav> <Switch> <Route path="/manatee"> <Manatee /> </Route> <Route path="/narwhal"> <Narwhal /> </Route> <Route path="/whale"> <Whale /> </Route> </Switch> </BrowserRouter> </div> ); } export default App;
Lưu các file . Khi bạn làm như vậy, trình duyệt sẽ làm mới. Khi bạn nhấp vào liên kết, trang sẽ không làm mới và trình duyệt sẽ không reload mã JavaScript:
Trong bước này, bạn đã thêm React Router vào dự án hiện tại của bạn . Bạn đã tạo một tuyến đường cho từng thành phần và bạn đã thêm một chuyển bằng cách sử dụng thành phần Link
để chuyển đổi giữa các tuyến đường mà không cần làm mới trang.
Trong bước tiếp theo, bạn sẽ thêm các tuyến phức tạp hơn hiển thị các thành phần khác nhau bằng cách sử dụng các tham số URL.
Bước 3 - Truy cập dữ liệu tuyến đường bằng Hooks
Trong bước này, bạn sẽ sử dụng các tham số và truy vấn URL để tạo các tuyến đường động. Bạn sẽ học cách lấy thông tin từ các tham số tìm kiếm với useLocation
Hook và cách đọc thông tin từ các URL động bằng useParams
Hook.
Đến cuối bước này, bạn sẽ biết cách truy cập thông tin lộ trình bên trong các thành phần của bạn và cách bạn có thể sử dụng thông tin đó để tải động các thành phần.
Giả sử bạn muốn thêm một cấp độ khác vào ứng dụng động vật có vú biển của bạn . Có nhiều loại cá voi và bạn có thể hiển thị thông tin về từng loại. Bạn có hai lựa chọn về cách thực hiện điều này: Bạn có thể sử dụng tuyến đường hiện tại và thêm một loại cá voi cụ thể với các tham số tìm kiếm, chẳng hạn như ?type=beluga
. Bạn cũng có thể tạo một tuyến mới bao gồm tên cụ thể sau URL cơ sở, chẳng hạn như /whale/beluga
. Hướng dẫn này sẽ bắt đầu với các tham số tìm kiếm, vì chúng linh hoạt và có thể xử lý nhiều truy vấn khác nhau.
Đầu tiên, tạo các thành phần mới cho các loài cá voi khác nhau.
Mở file mới Beluga.js
trong editor của bạn:
- nano src/components/Whale/Beluga.js
Thêm <h3>
với tên Beluga
:
import React from 'react'; export default function Beluga() { return( <h3>Beluga</h3> ); }
Làm điều tương tự đối với cá voi xanh. Mở file Blue.js
trong editor của bạn:
- nano src/components/Whale/Blue.js
Thêm <h3>
với tên Blue
:
import React from 'react'; export default function Blue() { return( <h3>Blue</h3> ); }
Lưu và đóng file .
Chuyển thông tin bổ sung với các tham số tìm kiếm
Tiếp theo, bạn sẽ chuyển thông tin cá voi làm tham số tìm kiếm . Điều này sẽ cho phép bạn chuyển thông tin mà không cần tạo URL mới.
Mở App.js
để bạn có thể thêm các liên kết mới:
- nano src/components/App/App.js
Thêm hai liên kết mới, một cho /whale?type=beluga
và một cho /whale?type=blue
:
import React from 'react'; import { BrowserRouter, Link, Route, Switch } from 'react-router-dom'; import './App.css'; import Manatee from '../Manatee/Manatee'; import Narwhal from '../Narwhal/Narwhal'; import Whale from '../Whale/Whale'; function App() { return ( <div className="wrapper"> <h1>Marine Mammals</h1> <BrowserRouter> <nav> <ul> <li><Link to="/manatee">Manatee</Link></li> <li><Link to="/narwhal">Narwhal</Link></li> <li><Link to="/whale">Whale</Link></li> <li><Link to="/whale?type=beluga">Beluga Whale</Link></li> <li><Link to="/whale?type=blue">Blue Whale</Link></li> </ul> </nav> <Switch> ... </Switch> </BrowserRouter> </div> ); } export default App;
Lưu và đóng file .
Nếu bạn nhấp vào các liên kết, bạn sẽ vẫn thấy trang cá voi thông thường. Điều này cho thấy rằng tuyến đường tiêu chuẩn vẫn hoạt động chính xác:
Vì bạn đang hiển thị chính xác thành phần Whale
, bạn cần cập nhật thành phần để kéo truy vấn tìm kiếm ra khỏi URL và sử dụng nó để hiển thị thành phần con chính xác.
Mở Whale.js
:
- nano src/components/Whale/Whale.js
Đầu tiên, nhập các thành phần Beluga
và Blue
. Tiếp theo, nhập một Hook có tên useLocation
từ useLocation
react-router-dom
:
import React from 'react'; import { useLocation } from 'react-router-dom'; import Beluga from './Beluga'; import Blue from './Blue'; export default function Whale() { return <h2>Whale</h2>; }
useLocation
Hook lấy thông tin vị trí từ trang web . Đây không phải là duy nhất đối với React Router. Đối tượng location
là một đối tượng tiêu chuẩn trên tất cả các trình duyệt . Nếu bạn mở console của trình duyệt và nhập window.location
, bạn sẽ nhận được một đối tượng có thông tin về URL của bạn.
Lưu ý thông tin vị trí bao gồm search
, nhưng cũng bao gồm các thông tin khác, chẳng hạn như pathname
và href
đầy đủ. useLocation
Hook sẽ cung cấp thông tin này cho bạn. Bên trong Whale.js
, hãy gọi useLocation
Hook. Hủy bỏ kết quả để rút ra trường search
. Đây sẽ là một chuỗi tham số, chẳng hạn như ?type=beluga
:
import React from 'react'; import { useLocation } from 'react-router-dom'; import Beluga from './Beluga'; import Blue from './Blue'; export default function Whale() { const { search } = useLocation(); return <h2>Whale</h2>; }
Có một số thư viện, chẳng hạn như query-string
, có thể phân tích cú pháp tìm kiếm cho bạn và chuyển đổi nó thành một đối tượng dễ đọc và cập nhật hơn. Trong ví dụ này, bạn có thể sử dụng biểu thức chính quy để lấy thông tin về type
cá voi.
Sử dụng phương thức .match
trên chuỗi tìm kiếm để lấy ra type
: search.match(/type=(.*)/)
. Các dấu ngoặc đơn bên trong biểu thức chính quy sẽ bắt khớp vào một mảng kết quả. Mục đầu tiên trong mảng là đối sánh đầy đủ: type=beluga
. Mục thứ hai là thông tin từ dấu ngoặc đơn: beluga
.
Sử dụng dữ liệu từ phương thức .match
để hiển thị thành phần con chính xác:
import React from 'react'; import { useLocation } from 'react-router-dom'; import Beluga from './Beluga'; import Blue from './Blue'; export default function Whale() { const { search } = useLocation(); const match = search.match(/type=(.*)/); const type = match?.[1]; return ( <> <h2>Whale</h2> {type === 'beluga' && <Beluga />} {type === 'blue' && <Blue />} </> ); }
Các ký hiệu ?.
được gọi là chuỗi tùy chọn . Nếu giá trị tồn tại, nó sẽ trả về giá trị. Nếu không, nó sẽ trả về undefined
. Điều này sẽ bảo vệ thành phần của bạn trong các trường hợp tham số tìm kiếm trống.
Lưu các file . Khi bạn làm như vậy, trình duyệt sẽ làm mới và sẽ hiển thị những con cá voi khác nhau:
Truy cập các tham số URL
Các tham số tìm kiếm hoạt động, nhưng chúng không phải là giải pháp tốt nhất trong trường hợp này. Nói chung, bạn sẽ sử dụng các thông số tìm kiếm để tinh chỉnh trang: chuyển đổi thông tin hoặc tải dữ liệu cụ thể. Trong trường hợp này, bạn không tinh chỉnh một trang; bạn đang tạo một trang tĩnh mới. May mắn là React Router cung cấp một cách để tạo các URL động bảo toàn dữ liệu biến được gọi là Tham số URL.
Mở App.js
:
- nano src/components/App/App.js
Thay vì chuyển thông tin cá voi dưới dạng tìm kiếm, bạn sẽ thêm nó trực tiếp vào chính URL. Điều đó nghĩa là bạn sẽ di chuyển seach vào URL thay vì thêm nó vào sau dấu ?
. Ví dụ: truy vấn /whale?type=blue
bây giờ sẽ là /whale/blue
:
import React from 'react'; import { BrowserRouter, Link, Route, Switch } from 'react-router-dom'; import './App.css'; import Manatee from '../Manatee/Manatee'; import Narwhal from '../Narwhal/Narwhal'; import Whale from '../Whale/Whale'; function App() { return ( <div className="wrapper"> <h1>Marine Mammals</h1> <BrowserRouter> <nav> <ul> <li><Link to="/manatee">Manatee</Link></li> <li><Link to="/narwhal">Narwhal</Link></li> <li><Link to="/whale">Whale</Link></li> <li><Link to="/whale/beluga">Beluga Whale</Link></li> <li><Link to="/whale/blue">Blue Whale</Link></li> </ul> </nav> <Switch> <Route path="/manatee"> <Manatee /> </Route> <Route path="/narwhal"> <Narwhal /> </Route> <Route path="/whale"> <Whale /> </Route> </Switch> </BrowserRouter> </div> ); } export default App;
Đến đây bạn cần tạo một tuyến đường mới có thể bắt được cả /whale/beluga
và /whale/blue
. Bạn có thể thêm chúng theo cách thủ công, nhưng điều này sẽ không hiệu quả trong các trường hợp mà bạn không biết trước tất cả các khả năng, chẳng hạn như khi bạn có danh sách user hoặc dữ liệu động khác.
Thay vì tạo một đường dẫn cho từng đường dẫn, hãy thêm một tham số URL vào đường dẫn hiện tại. Tham số URL là một từ khóa được mở đầu bằng dấu hai chấm. React Router sẽ sử dụng tham số như một ký tự đại diện và sẽ trùng với bất kỳ tuyến nào có chứa mẫu đó.
Trong trường hợp này, hãy tạo một từ khóa :type
. Đường path
đầy đủ sẽ là /whale/:type
. Điều này sẽ trùng với bất kỳ tuyến nào bắt đầu bằng /whale
và nó sẽ lưu thông tin biến bên trong một biến tham số được gọi là type
. Tuyến đường này sẽ không khớp /whale
, vì nó không chứa tham số bổ sung.
Bạn có thể thêm /whale
làm tuyến sau tuyến mới hoặc bạn có thể thêm nó trước tuyến /whale/:type
với từ khóa exact
.
Thêm một tuyến mới của /whale/:type
và thêm một thuộc tính exact
vào tuyến hiện tại:
import React from 'react'; import { BrowserRouter, Link, Route, Switch } from 'react-router-dom'; import './App.css'; import Manatee from '../Manatee/Manatee'; import Narwhal from '../Narwhal/Narwhal'; import Whale from '../Whale/Whale'; function App() { return ( <div className="wrapper"> <h1>Marine Mammals</h1> <BrowserRouter> <nav> <ul> <li><Link to="/manatee">Manatee</Link></li> <li><Link to="/narwhal">Narwhal</Link></li> <li><Link to="/whale">Whale</Link></li> <li><Link to="/whale/beluga">Beluga Whale</Link></li> <li><Link to="/whale/blue">Blue Whale</Link></li> </ul> </nav> <Switch> <Route path="/manatee"> <Manatee /> </Route> <Route path="/narwhal"> <Narwhal /> </Route> <Route exact path="/whale"> <Whale /> </Route> <Route path="/whale/:type"> <Whale /> </Route> </Switch> </BrowserRouter> </div> ); } export default App;
Lưu và đóng file . Đến đây bạn đang chuyển thông tin mới, bạn cần truy cập nó và sử dụng thông tin để hiển thị các thành phần động.
Mở Whale.js
:
- nano src/components/Whale/Whale.js
Nhập useParams
Hook. Thao tác này sẽ kết nối với bộ định tuyến của bạn và kéo bất kỳ tham số URL nào vào một đối tượng. Hủy cấu trúc đối tượng để kéo ra trường type
. Xóa mã để phân tích cú pháp search
và sử dụng tham số để hiển thị có điều kiện các thành phần con:
import React from 'react'; import { useParams } from 'react-router-dom'; import Beluga from './Beluga'; import Blue from './Blue'; export default function Whale() { const { type } = useParams(); return ( <> <h2>Whale</h2> {type === 'beluga' && <Beluga />} {type === 'blue' && <Blue />} </> ); }
Lưu và đóng file . Khi bạn làm như vậy, trình duyệt sẽ làm mới và bạn có thể sử dụng các URL mới, chẳng hạn như http://localhost:3000/whale/beluga
:
Tham số URL là một cách rõ ràng để chuyển dữ liệu có điều kiện. Chúng không linh hoạt như các tham số tìm kiếm, có thể được kết hợp hoặc sắp xếp lại, nhưng chúng rõ ràng hơn và dễ dàng hơn cho các công cụ tìm kiếm lập index .
Trong bước này, bạn đã chuyển dữ liệu biến bằng cách sử dụng tham số tìm kiếm và tham số URL. Bạn cũng đã sử dụng useLocation
và useParams
Hooks để kéo thông tin ra ngoài và kết xuất các thành phần có điều kiện.
Nhưng có một vấn đề: Danh sách các tuyến đường ngày càng dài và bạn bắt đầu nhận được các tuyến trùng lặp gần với các tuyến /whale
và /whale/:type
. React Router cho phép bạn tách các tuyến con trực tiếp trong thành phần, nghĩa là bạn không cần phải có toàn bộ danh sách trong một thành phần duy nhất. Trong bước tiếp theo, bạn sẽ hiển thị các tuyến trực tiếp bên trong các thành phần con.
Bước 4 - Làm tổ các tuyến đường
Các tuyến đường có thể phát triển và trở nên phức tạp hơn. React Router sử dụng các tuyến đường lồng nhau để hiển thị thông tin định tuyến cụ thể hơn bên trong các thành phần con. Trong bước này, bạn sẽ sử dụng các tuyến đường lồng nhau và thêm các tuyến đường trong các thành phần khác nhau. Đến cuối bước này, bạn sẽ có các tùy chọn khác nhau để hiển thị thông tin của bạn .
Trong bước cuối cùng, bạn đã thêm các tuyến đường bên trong App.js
Điều này có một số ưu điểm: Nó giữ tất cả các tuyến đường ở một nơi, về cơ bản là tạo sơ đồ trang web cho ứng dụng của bạn. Nhưng nó có thể dễ dàng phát triển và khó đọc và khó bảo trì. Các tuyến lồng nhau group trực tiếp thông tin định tuyến của bạn trong các thành phần sẽ hiển thị các thành phần khác, cho bạn khả năng tạo các mẫu nhỏ trong toàn bộ ứng dụng của bạn .
Mở App.js
:
- nano src/components/App/App.js
Loại bỏ tuyến đường /whale/:type
và loại bỏ chỗ dựa exact
để bạn chỉ có tuyến đường cá voi:
import React from 'react'; import { BrowserRouter, Link, Route, Switch } from 'react-router-dom'; import './App.css'; import Manatee from '../Manatee/Manatee'; import Narwhal from '../Narwhal/Narwhal'; import Whale from '../Whale/Whale'; function App() { return ( <div className="wrapper"> <h1>Marine Mammals</h1> <BrowserRouter> <nav> <ul> <li><Link to="/manatee">Manatee</Link></li> <li><Link to="/narwhal">Narwhal</Link></li> <li><Link to="/whale">Whale</Link></li> <li><Link to="/whale/beluga">Beluga Whale</Link></li> <li><Link to="/whale/blue">Blue Whale</Link></li> </ul> </nav> <Switch> <Route path="/manatee"> <Manatee /> </Route> <Route path="/narwhal"> <Narwhal /> </Route> <Route path="/whale"> <Whale /> </Route> </Switch> </BrowserRouter> </div> ); } export default App;
Lưu và đóng file .
Tiếp theo, mở Whale.js
. Đây là nơi bạn sẽ thêm tuyến đường lồng nhau.
- nano src/components/Whale/Whale.js
Bạn cần phải làm hai điều. Đầu tiên, lấy đường dẫn hiện tại với useRouteMatch
Hook. Tiếp theo, kết xuất các thành phần <Switch>
và <Route>
để hiển thị các thành phần chính xác.
Nhập useRouteMatch
. Thao tác này sẽ trả về một đối tượng chứa path
và url
. Phá hủy đối tượng để lấy path
. Bạn sẽ sử dụng điều này làm cơ sở cho các tuyến đường mới của bạn :
import React from 'react'; import { useRouteMatch } from 'react-router-dom'; import Beluga from './Beluga'; import Blue from './Blue'; export default function Whale() { const { path } = useRouteMatch(); return ( <> <h2>Whale</h2> {type === 'beluga' && <Beluga />} {type === 'blue' && <Blue />} </> ); }
Tiếp theo, nhập Switch
và Route
để bạn có thể thêm các tuyến đường mới. Các tuyến đường mới của bạn sẽ giống như bạn đã thực hiện trong App.js
, nhưng bạn không cần phải bọc chúng bằng BrowserRouter
. Thêm các tuyến đường mới, nhưng đặt trước tuyến đường bằng path
. Thành phần mới sẽ hiển thị chính xác nơi bạn đặt chúng, vì vậy hãy thêm các tuyến mới sau <h2>
:
import React from 'react'; import { Switch, Route, useRouteMatch } from 'react-router-dom'; import Beluga from './Beluga'; import Blue from './Blue'; export default function Whale() { const { path } = useRouteMatch(); return ( <> <h2>Whale</h2> <Switch> <Route path={`${path}/beluga`}> <Beluga /> </Route> <Route path={`${path}/blue`}> <Blue /> </Route> </Switch> </> ); }
Lưu các file . Khi bạn làm như vậy, trình duyệt sẽ làm mới và bạn có thể truy cập các tuyến đường con.
Đây là một mã bổ sung nhỏ, nhưng nó giữ cho các tuyến con nằm cùng với cha mẹ của chúng. Không phải tất cả các dự án đều sử dụng các tuyến đường lồng nhau: một số thích có một danh sách rõ ràng. Đó là vấn đề về sự ưu tiên và nhất quán của đội. Chọn tùy chọn tốt nhất cho dự án của bạn và bạn luôn có thể cấu trúc lại sau.
Trong bước này, bạn đã thêm các tuyến đường lồng nhau vào dự án của bạn . Bạn đã kéo ra đường dẫn hiện tại bằng useRouteMatch
Hook và thêm các đường dẫn mới trong một thành phần để hiển thị các thành phần mới bên trong một thành phần cơ sở.
Kết luận
React Router là một phần quan trọng của bất kỳ dự án React nào. Khi bạn xây dựng các ứng dụng trang đơn, bạn sẽ sử dụng các tuyến đường để tách ứng dụng của bạn thành các phần có thể sử dụng được mà user có thể truy cập dễ dàng và nhất quán.
Khi bạn bắt đầu tách các thành phần của bạn thành các tuyến, bạn có thể tận dụng lợi thế của việc tách mã , duy trì trạng thái thông qua các tham số truy vấn và các công cụ khác để cải thiện trải nghiệm user .
Nếu bạn muốn đọc thêm các hướng dẫn về React, hãy xem trang Chủ đề React của ta hoặc quay lại trang Cách viết mã trong chuỗi React.js .
Các tin liên quan