paint-brush
Các kỹ thuật Advanced React Router V6: Vượt ra ngoài những điều cơ bảnby@sojinsamuel
6,014
6,014

Các kỹ thuật Advanced React Router V6: Vượt ra ngoài những điều cơ bản

Sojin Samuel11m2023/07/02
Read on Terminal Reader

React Router là một công cụ tuyệt vời cho phép chúng tôi tạo điều hướng động và mượt mà trong các ứng dụng React của mình. Có một số kỹ thuật ít được biết đến hơn có thể nâng khả năng định tuyến của bạn lên một cấp độ hoàn toàn mới. Chúng tôi sẽ đề cập: Xử lý trang 404 khét tiếng. Tạo chỉ báo trang đang hoạt động để đánh dấu tuyến đường hiện tại. Sử dụng các hook `useNavigate` và `useLocation`.
featured image - Các kỹ thuật Advanced React Router V6: Vượt ra ngoài những điều cơ bản
Sojin Samuel HackerNoon profile picture
0-item
1-item

Tôi thực sự vui mừng được chia sẻ một số kỹ thuật React Router nâng cao với bạn ngày hôm nay. React Router là một công cụ tuyệt vời cho phép chúng tôi tạo điều hướng động và mượt mà trong các ứng dụng React của mình.


Mặc dù nó thường được sử dụng cho các nhu cầu định tuyến cơ bản, nhưng có một số kỹ thuật ít được biết đến hơn có thể nâng khả năng định tuyến của bạn lên một cấp độ hoàn toàn mới.


Hôm nay, tôi sẽ chia sẻ một số mục yêu thích của tôi mà tôi đã khám phá ra theo thời gian.


Chúng tôi sẽ bao gồm:

  1. Xử lý trang 404 khét tiếng.
  2. Tạo chỉ báo trang đang hoạt động để đánh dấu tuyến đường hiện tại.
  3. Sử dụng móc useNavigateuseLocation .


Vào thời điểm bạn đọc xong bài viết này, bạn sẽ nắm vững các kỹ thuật React Router nâng cao này và cảm thấy tự tin khi áp dụng chúng trong các dự án của riêng mình.


Vì vậy, hãy cùng nhau đi sâu vào và nâng cao kỹ năng định tuyến của chúng ta!


Bạn đã sẵn sàng chưa? Bắt đầu nào!

Xử lý trang 404


Khi làm việc trên các dự án lớn hơn, điều cần thiết là phải quan tâm đến các tuyến đường không thể tìm thấy. Chúng tôi thường gọi các tuyến này là tuyến 404 vì chúng trả về mã trạng thái HTTP 404 khi không tìm thấy tài liệu trên máy chủ.


Nhân tiện, nếu bạn là người yêu mèo, bạn có thể thích xem http.cat .


Bây giờ, hãy đi sâu vào việc tạo một Tuyến đường đặc biệt sẽ được kích hoạt bất cứ khi nào không có tuyến đường nào khác khớp với URL hiện tại trong trình duyệt.

 import {BrowserRouter, Routes, Route} from "react-router-dom"; function App() { return <BrowserRouter> <Routes> <Route path="/" element={<p>Landing page</p>}></Route> <Route path="/products" element={<p>Products page</p>}></Route> <Route path="*" element={<p>404 page</p>}></Route> </Routes> </BrowserRouter> }

Khi truy cập vào trang chính / , người dùng sẽ được dẫn đến Landing page. Điều hướng đến trang /products sẽ dẫn họ đến trang Sản phẩm. Tuy nhiên, nếu bất kỳ liên kết nào khác được truy cập không tương ứng với một tuyến đường cụ thể, trang 404 sẽ được hiển thị.


Lý do đằng sau hành vi này là việc triển khai <Route> chuyên biệt cho trang 404, trong đó thuộc tính đường dẫn được đặt thành * . Cấu hình này đảm bảo rằng Bộ định tuyến React sẽ sử dụng độc quyền tuyến đường này khi không có tuyến đường nào khác phù hợp. Vị trí cụ thể của Tuyến đường 404 là không quan trọng và có thể được định vị ở bất kỳ đâu trong phần <Routes>...</Routes> , như một thành phần không thể thiếu của nó.

trang hoạt động

Một cách khác mà các ứng dụng có thể sử dụng các tuyến đường một cách thiết thực là làm nổi bật trang hiện đang hoạt động trong menu.


Hãy tưởng tượng bạn có một menu điều hướng với hai liên kết:


  1. Trang chủ - Liên kết này đưa người dùng đến trang chính / .

  2. Giới thiệu - Liên kết này đưa người dùng đến trang giới thiệu /about .


Với React Router, có thể tự động đánh dấu liên kết About khi người dùng đang ở trên /about route. Tương tự, bạn có thể đánh dấu liên kết Trang chủ khi người dùng đang ở trên / tuyến đường. Phần tốt nhất là bạn có thể đạt được điều này mà không cần các điều kiện phức tạp.


Đây là một cách đơn giản để làm cho nó hoạt động:

 import {NavLink} from "react-router-dom"; function getClassName({isActive}) { if (isActive) { return "active"; // CSS class } } function App() { return <ul> <li> <NavLink to="/" className={getClassName}>Home</NavLink> </li> <li> <NavLink to="/about" className={getClassName}>About</NavLink> </li> </ul> }


Mã bạn thấy ở trên cần một số CSS để làm cho lớp active động. Vì vậy, chúng tôi có thể nâng cao nó bằng cách làm cho liên kết menu của trang hiện đang hoạt động xuất hiện đậm và nổi bật.

 .active { font-weight: bold; }


Thuộc tính className của phần tử NavLink có thể linh hoạt chấp nhận một hàm thay vì chỉ một chuỗi. Khi bạn quyết định sử dụng một hàm, nó sẽ được cung cấp một đối tượng làm tham số và đối tượng này sẽ có thuộc tính isActive đã được đặt sẵn trên đó. Để dễ dàng truy cập thuộc tính này trong hàm, chúng tôi sử dụng hàm hủy bằng cách đưa {isActive} vào tham số.


Tiếp theo, chúng tôi tiến hành xác minh xem isActive có giữ giá trị trung thực hay không. Nếu đúng như vậy, chúng tôi sẽ trả về tên lớp CSS active .


Khi đường dẫn hiện tại trong React Router khớp với thuộc tính to của thành phần NavLink , hàm isActive sẽ đánh giá thành giá trị boolean.


Do đó, React Router sẽ bao gồm lớp active một cách liền mạch trong phần tử <NavLink /> tương ứng, cho biết đây là tuyến hiện đang hoạt động.

phiên bản ngắn hơn

Nếu bạn thích cách tiếp cận ngắn hơn, bạn có thể sử dụng toán tử bậc ba để cấu trúc lại mã được đề cập ở trên. Toán tử này cung cấp một cách để thay thế câu lệnh if/else bằng cách sử dụng định dạng: condition ? truthy expression : falsy expression .

Tôi không thực sự sử dụng toán tử bậc ba nhiều vì nó thường có thể làm cho mã khó đọc hơn. Tuy nhiên, nó được chấp nhận để sử dụng trong trường hợp này.


Hãy xem xét những điều sau đây như một ví dụ:

 function getClassName({isActive}) { if (isActive) { return "active"; } else { return ""; } }


Bạn có thể thay thế đoạn mã trên bằng cách tiếp cận sau:

 function getClassName({isActive}) { return isActive ? "active" : ""; }


Bạn chỉ cần đảm bảo rằng câu lệnh return được đặt bên ngoài toán tử bậc ba. Khi điều kiện isActive là đúng, biểu thức sau ? sẽ được thực hiện "active" . Nếu không, biểu thức sau : sẽ được thực thi "" .


Bây giờ, chúng ta có thể loại bỏ nhu cầu về một định nghĩa hàm riêng gọi là getClassName . Thay vào đó, chúng ta có thể sử dụng hàm mũi tên như sau: ({isActive}) => isActive ? "active" : "" .


Nếu bạn thấy thay đổi này quá khó đọc, bạn có thể tiếp tục sử dụng một chức năng riêng như trước.

Mã cuối cùng sẽ trông như thế này:

 import {NavLink} from "react-router-dom"; function App() { return <ul> <li> <NavLink to="/" className={({isActive}) => isActive ? "active" : ""}>Home</NavLink> </li> <li> <NavLink to="/about" className={({isActive}) => isActive ? "active" : ""}>About</NavLink> </li> </ul> }

Oh boy, tôi thực tế có thể nghe thấy suy nghĩ của bạn!

Sojin, bạn đã đi và phá vỡ nguyên tắc DRY, phải không?

Đây chỉ là một ví dụ. Không cần phải lo hết 😀

Lựa chọn giữa Liên kết và NavLink: Điều gì khiến chúng khác biệt?

Bạn có thể đã nhận thấy rằng tôi đang sử dụng NavLink thay vì người bạn thông thường của chúng ta, Link . Nhưng đừng lo lắng, hãy để tôi giải thích tại sao. Bạn thấy đấy, thành phần <Link /> không cho phép bạn sử dụng định nghĩa hàm cho chỗ dựa className . Vâng, điều đó có thể gây ngạc nhiên, nhưng đó chỉ là cách bạn làm việc với <Link /> .


Một lỗi phổ biến mà tôi từng thấy là các nhà phát triển React mới vào nghề đang cố gắng sử dụng các định nghĩa hàm trong chỗ dựa className của thành phần <Link /> , điều này đơn giản là không hoạt động.


Nếu bạn quan tâm, tôi có thể viết một bài báo về chủ đề này. Chỉ cần cho tôi biết trong các ý kiến!

sử dụngNavigate

Trong một số trường hợp nhất định, bạn có thể cần di chuyển các trang trong ứng dụng React của mình theo chương trình. Ví dụ: để chuyển hướng khách truy cập đến một trang cụ thể, bạn có thể gửi yêu cầu và đợi phản hồi.


Dưới đây là một vài ví dụ:

  • Nếu người dùng chưa đăng nhập, hãy gửi họ đến trang đăng nhập.
  • Sau khi yêu cầu getLogin hoàn tất thành công, hãy chuyển hướng người dùng đến /dashboard .


Điều này yêu cầu sử dụng hook useNavigate() , hàm này trả về một hàm mà bạn có thể sử dụng để chuyển hướng người dùng đến một tuyến đường mới theo chương trình.


Hãy xem:

 import React, {useEffect} from "react"; import {useNavigate} from "react-router-dom"; function HelpPage() { const navigate = useNavigate(); useEffect(() => { const isLoggedIn = window.localStorage.getItem("isLoggedIn"); if (!isLoggedIn) { navigate("/login"); } }, []); return <h2>Help page</h2>; }

Sử dụng BrowserRouter là điều cần thiết!

Trong ví dụ này, chúng tôi đang kiểm tra xem localStorage có giá trị được gán cho khóa isLoggedIn không. Nếu không, chúng tôi sẽ chuyển hướng người dùng đến trang /login bằng chức năng navigate("/login") .


Để làm cho nó hoạt động, chỉ cần nhớ sử dụng hook useNavigate() trong một thành phần được lồng bên trong thành phần <BrowserRouter /> . Nếu không, nó sẽ không hoạt động bình thường.


Chẳng hạn, ví dụ sau sẽ không hoạt động:

 import React from "react"; import {BrowserRouter, useNavigate} from "react-router-dom"; function App() { // ❌ This breaks because the component was not wrapped by BrowserRouter, but its children are. const history = useNavigate(); return <BrowserRouter> {/* ... */} </BrowserRouter>; }

Nếu bạn đang cố gắng sử dụng hook useNavigate() bên trong thành phần App() , bạn có thể gặp trục trặc nhỏ. Đó là bởi vì nó sẽ không hoạt động trừ khi bạn bọc thành phần App() bằng <BrowserRouter /> .


Nhưng đừng lo!


Tin vui là tất cả các thành phần con bên trong Ứng dụng sẽ tự động được bao bọc bởi <BrowserRouter /> , vì vậy bạn có thể thoải mái sử dụng useNavigate() trong các thành phần con đó mà không gặp bất kỳ sự cố nào.


Tuy nhiên, nếu bạn thực sự cần sử dụng useNavigate() trong chính thành phần <App /> , thì có một giải pháp đơn giản. Bạn chỉ cần tạo một thành phần chính bao bọc <App /> và đảm bảo di chuyển <BrowserRouter /> bên trong thành phần chính đó. Khi bạn làm điều đó, bạn sẽ sẵn sàng và có thể sử dụng useNavigate() trong thành phần <App /> theo ý muốn của bạn 💗

Đảm bảo khả năng truy cập và sử dụng liên kết phù hợp

Khi nói đến việc làm cho trang web của bạn có thể truy cập được, điều quan trọng là phải chú ý đến cách các liên kết của bạn được cấu trúc. Để đảm bảo điều đó, bạn nên sử dụng các phần tử <Link /> thay vì các phương thức khác.


Tại sao?


Chà, những phần tử này sẽ tự động hiển thị dưới dạng thẻ <a> , được biết đến với các tính năng trợ năng của chúng .

Bây giờ, đây là một mẹo thân thiện: tránh thay thế các phần tử <Link /> thông thường của bạn bằng phương thức .push() do useNavigate() cung cấp. Chỉ nên sử dụng phương pháp này trong trường hợp không thể sử dụng phần tử <Link /> .


Khi nào điều đó xảy ra?

Thông thường, đó là khi bạn cần chuyển hướng người dùng theo chương trình dựa trên logic nhất định, chẳng hạn như kết quả của thao tác fetch() .

sử dụngLocation

Điều gì sẽ xảy ra nếu bạn muốn thực thi một đoạn mã mỗi khi React Router đưa bạn đến một địa chỉ mới?

Bạn có thể thực hiện điều đó một cách dễ dàng với sự trợ giúp của hook useLocation . Nhưng trước khi đi sâu vào chi tiết, hãy khám phá một số tình huống mà điều này có thể hữu ích. Một trong những trường hợp sử dụng phổ biến nhất là gửi sự kiện xem trang tới dịch vụ phân tích của bạn, chẳng hạn như Google Analytics.


Tuy nhiên, điều đáng nói là Google Analytics 4 giờ đây sẽ tự động xử lý việc này, do đó, bạn không nhất thiết phải tự mình triển khai.


Tuy nhiên, việc tìm hiểu về hook useLocation vẫn có giá trị vì bạn có thể tìm thấy các mục đích khác cho nó. Chẳng hạn, bạn có thể sử dụng nó để tích hợp với các thư viện và dịch vụ phân tích khác hoặc để thực hiện các hành động cụ thể dựa trên các tuyến đã truy cập.


Các khả năng là vô tận!

sử dụng Móc định vị

Móc useLocation cực kỳ tiện dụng vì nó cung cấp cho bạn thông tin về tuyến đường hiện đang được sử dụng.


Dưới đây là hướng dẫn thân thiện về cách sử dụng hook useLocation:

 import {BrowserRouter, Routes, Route, useLocation} from "react-router-dom"; import {createRoot} from "react-dom/client"; function App() { const location = useLocation(); console.log(location.pathname); return <Routes> {/* routes here... */} </Routes> } createRoot(document.querySelector("#react-root")).render(<BrowserRouter><App /></BrowserRouter>);


Bây giờ, bạn có thể truy cập thông tin tuyến đường thông qua biến vị trí. Đó là một đối tượng chứa pathname hiện tại.


Để tìm ra tuyến đường mà người dùng hiện đang duyệt, chỉ cần sử dụng location.pathname . Nó sẽ cung cấp cho bạn một cái gì đó như / , /about hoặc bất kỳ tuyến đường nào khác mà bạn đã thiết lập.


Hãy nhớ rằng, giống như với hook useNavigate , điều quan trọng là mã của bạn phải chạy bên trong một thành phần được bao bọc bởi <BrowserRouter /> . Nếu không, hook useLocation sẽ không thực hiện được điều kỳ diệu của nó.

Ứng phó với Thay đổi Vị trí

Khi vị trí thay đổi, bạn có thể sử dụng hook useLocation để truy cập đường dẫn URL hiện tại trong React Router. Bằng cách bọc mã của bạn bằng hook useEffect và đặt phần phụ thuộc vào location , bạn có thể chạy một đoạn mã cụ thể bất cứ khi nào có điều hướng đến một URL mới.


Đây là một ví dụ về cách thực hiện:

 import React, {useEffect} from "react"; import {BrowserRouter, Routes, Route, useLocation} from "react-router-dom"; import {createRoot} from "react-dom/client"; function App() { const location = useLocation(); // run a piece of code on location change useEffect(() => { console.log(location.pathname); // send it to analytic, or do some conditional logic here }, [location]); return <Routes> {/* routes here... */} </Routes> } createRoot(document.querySelector("#react-root")).render(<BrowserRouter><App /></BrowserRouter>);

Bất cứ khi nào người dùng di chuyển đến một tuyến đường mới trong quá trình điều hướng, mã bên trong hook useEffect sẽ chạy và thực hiện công việc của nó. Về cơ bản, đó là một cách để đảm bảo rằng mã cụ thể được thực thi bất cứ khi nào có sự thay đổi trong đối tượng vị trí.

Tốt lắm, giờ bạn đã trở thành Chuyên gia React Router 🥳

Tóm lại, bài viết này đã giúp bạn hiểu sâu hơn về React Router. Mặc dù bạn có thể không sử dụng tất cả các tính năng được thảo luận ở đây. Tuy nhiên, thật tuyệt vời khi bạn biết về chúng. Nếu bạn thấy mình cần kết hợp chức năng tương tự trong tương lai, bạn sẽ biết chính xác nơi cần tìm. Vì vậy, hãy nhớ lưu hoặc đánh dấu bài đăng này để dễ dàng tham khảo. Và hãy nhớ rằng, nếu bạn có bất kỳ câu hỏi nào hoặc cần hỗ trợ thêm, vui lòng liên hệ với tôi trên Twitter. Tôi ở đây để giúp đỡ!