Một ứng dụng của chúng ta sẽ có rất nhiều trang, tuy nhiên khi chúng ta chuyển trang thì lại không được reload lại trang để tối ưu, React cũng đã cung cấp cho chúng ta thư viện Navigation, tuy nhiên chúng hãy thử sức tự mình xây dựng phần này xem có được không nhé.

Khởi tạo dự án

Đầu tiên chúng ta sẽ khởi tạo dự án react-hook-example bằng cách sử dụng câu lệnh:

yarn create vite react-navigation-example

Bạn đừng quên lựa chọn framework là ReactJS và ngôn ngữ là Typescript nhé.
Sau khi bạn khởi tạo dự án xong hãy cd vào thư mục react-hook-example vừa được tạo và gõ lệnh yarn để tải các thư viện cần thiết và chạy lệnh yarn dev để khởi chạy server và bạn có thể truy cập vào trang web thông qua địa chỉ: http://localhost:5173/

Khởi tạo các trang

Chúng ta sẽ có các trang với mối liên kết như sau:

Ở đây chúng ta sẽ có 3 trang:

  1. Trang entry: Chứa 2 lối vào cho 2 trang Page 1 và Page 2.
  2. Trang Page 1: Chứa nội dung và một nút để trở lại trang Entry.
  3. Trang Page 2: Chứa nội dung và một nút để sang trang Page 1.
    Mã nguồn dùng chung common.tsx sẽ như sau:
export interface PageProps {
    setCurrentViewURI: (uri: string) => void;
}

Mã nguồn của trang Entry.tsx sẽ như sau:

import reactLogo from './assets/react.svg'
import { PageProps } from './common'
import viteLogo from '/vite.svg'

const Entry: React.FC<PageProps> = ({ setCurrentViewURI }) => {
  return (
    <>
      <div>
        <a href="https://vitejs.dev" target="_blank">
          <img src={viteLogo} className="logo" alt="Vite logo" />
        </a>
        <a href="https://react.dev" target="_blank">
          <img src={reactLogo} className="logo react" alt="React logo" />
        </a>
      </div>
      <h1>Vite + React</h1>
      <div className="card">
        <button onClick={() => setCurrentViewURI("/page1")}>
          Move to Page 1
        </button>
        <button onClick={() => setCurrentViewURI("/page2")}>
          Move to Page 2
        </button>
        <p>
          Edit <code>src/App.tsx</code> and save to test HMR
        </p>
      </div>
      <p className="read-the-docs">
        Click on the Vite and React logos to learn more
      </p>
    </>
  )
}

export default Entry

Mã nguồn của trang Page1.tsx sẽ như sau:

import { PageProps } from "./common"

const Page1: React.FC<PageProps> = ({ setCurrentViewURI }) => {
  return (
    <>
      <h1>Techmaster</h1>
      <div className="card">
        <p>Page 1</p>
        <button onClick={() => setCurrentViewURI("/entry")}>
          Back to Entry
        </button>
      </div>
    </>
  )
}

export default Page1

Mã nguồn của trang Page2.tsx sẽ như sau:

import { PageProps } from "./common"

const Page1: React.FC<PageProps> = ({ setCurrentViewURI }) => {
  return (
    <>
      <h1>Techmaster</h1>
      <div className="card">
        <p>Page 2</p>
        <button onClick={() => setCurrentViewURI("/page1")}>
          Back to Page 1
        </button>
      </div>
    </>
  )
}

export default Page1

Navigation

Chúng ta sẽ thay đổi mã nguồn App.tsx thành như sau:

import { useState } from 'react'
import './App.css'
import Entry from './Entry'
import Page1 from './Page1';
import Page2 from './Page2';

function App() {
  const [currentViewURI, setCurrentViewURI] = useState("/entry")

  let view;
  switch(currentViewURI) {
    case "/entry":
      view = <Entry setCurrentViewURI={setCurrentViewURI} />;
      break;
    case "/page1":
      view = <Page1 setCurrentViewURI={setCurrentViewURI} />;
      break;
    case "/page2":
      view = <Page2 setCurrentViewURI={setCurrentViewURI} />;
      break;
    default:
      view = <Entry setCurrentViewURI={setCurrentViewURI} />;
      break;
  };
  window.history.pushState('', '', currentViewURI);
  return view;
}

export default App

Ở đây chúng ta khai báo một biến trạng thái currentViewURI và một hàm set trạng thái là setCurrentViewURI, chúng ta cũng sẽ truyền hàm này vào cho các trang để các trang có thể thay đổi trạng thái chính là các uri tương ứng với từng trang.
Chúng ta cũng sẽ có một switch case để tương ứng với từng uri thì sẽ chuyển sang trang. Mặc định thì sẽ là trang entry với giao diện như sau:

Khi chúng ta nhấn nút Move to Page 1 thì nó sẽ ra trang 1:

Nhấn vào Back to Entry thì sẽ trở về trang entry.
Khi nhấn vào nút Move to Page 2 thì sẽ chuyển sang Page 2:

Khi nhấn vào vào Back to Page 1 thì sẽ trở về trang 1.
Nhìn thì có vẻ đơn giản từ mã nguồn cho đến tư tưởng, nhưng đây là mã nguồn cơ sở để chúng ta có thể tạo ra navigation cao cấp hơn cho những dự án phức tạp.

Tổng kết

Như vậy chúng ta đã cùng nhau tạo ra một navigation đơn giản thông qua việc quản lý trạng thái, trong bài tiếp theo chúng ta có thể tạo ra một navigation phức tạp hơn bằng cách sử dụng memento design pattern.


Cám ơn bạn đã quan tâm đến bài viết này. Để nhận được thêm các kiến thức bổ ích bạn có thể:

  1. Đọc các bài viết của TechMaster trên facebook: https://www.facebook.com/techmastervn
  2. Xem các video của TechMaster qua Youtube: https://www.youtube.com/@TechMasterVietnam nếu bạn thấy video/bài viết hay bạn có thể theo dõi kênh của TechMaster để nhận được thông báo về các video mới nhất nhé.
  3. Chat với techmaster qua Discord: https://discord.gg/yQjRTFXb7a