Viblo CTF
+1

Tìm hiểu React Router 2021 - Phần 1

Mở đầu

Nếu bạn đang xây dựng ứng dụng React, bạn chắc chắn sẽ cần sử dụng một Router chuyên dụng để hiển thị các trang và điều hướng người dùng của bạn.

Và hôm nay chúng ta sẽ cùng tìm hiểu React Router để dễ dàng điều hướng người dùng trong ứng dụng của mình.

Install React Router

Để sử dụng React Router bạn cần phải cài đặt package thích hợp.

Về mặt kỹ thuật, có 3 package khác nhau: React Router, React Router DOM, và React Router Native.

React Router DOM dành cho các ứng dụng web và React Router Native dành cho các ứng dụng mobile mà được tạo bằng React Native.

Vậy, điều đầu tiên chúng ta cần làm là cài đặt React Router DOM sử dụng npm hoặc yarn

npm install react-router-dom

Basic Router Setup

Sau khi cài đặt xong, để bắt đầu sử dụng React router ta chỉ cần import BrowserRouter trong component của mình.

Lưu ý :

  • Ngoài BrowserRouter thì react-router-dom còn cung cấp nhiều loại routers khác mà chúng ta sẽ không đi sâu vào tìm hiểu trong bài viết này.
  • Và khi import thì mọi người sẽ thường đặt bí danh cho BrowserRouter đơn giản là Router.

Nếu chúng ta muốn cung cấp các routes trong toàn bộ ứng dụng thì nó cần phải được bọc xung quanh toàn bộ component tree

Đó là lý do tại sao bạn sẽ thường thấy nó được bao bọc xung quanh hoặc bên trong main component

import { BrowserRouter as Router } from 'react-router-dom';

export default function App() {
  return (
    <Router>
      {/* routes go here, as children */}
    </Router>
  )

Và chức năng chính của BrowserRouter là để chúng ta có thể khai báo các routers riêng lẻ trong ứng dụng của mình.

Route Component

Tiếp theo là Route component.

Trong component Router, chúng ta sẽ khai báo các routes. Và có thể khai báo bao nhiêu route tùy thích.

Mỗi route cần cung cấp ít nhất 2 props, đó là pathcomponent (hoặc render)

import { BrowserRouter as Router, Route } from 'react-router-dom';

export default function App() {
  return (
    <Router>
      <Route path="/about" component={About} />
    </Router>
  );
}

function About() {
  return <>about</>   
}

Prop path đơn giản là chỉ định path của ứng dụng.

Hai prop render , component được sử dụng để hiển thị một component cụ thể cho path của chúng ta.

Trong khi component props chỉ có thể nhận một tham chiếu đến một component nhất định thì render thường được sử dụng để thêm những điều kiện logic để render một route những component khác nhau.

Và đối với render, chúng ta có thể sử dụng để tham chiếu đến một component hoặc sử dụng một function

import { BrowserRouter as Router, Route } from "react-router-dom";

export default function App() {
  return (
    <Router>
      <Route path="/" render={() => <Home />} />
      <Route path="/about" component={About} />
    </Router>
  );
}

function Home() {
  return <>home</>;
}

function About() {
  return <>about</>;
}

Cần lưu ý rằng bạn hoàn toàn có thể bỏ 2 props render hoặc component và sử dụng component mà bạn muốn liên kết với route dưới dạng component con của Route

import { BrowserRouter as Router, Route } from "react-router-dom";

export default function App() {
  return (
    <Router>
      <Route path="/about">
        <About />
      </Route>
    </Router>
  );
}

Cuối cùng, nếu muốn một component (ví dụ như navbar) hiển thị trên mọi trang.

Chỉ cần đặt nó vẫn nằm trong Routernhưng ở trên (hoặc bên dưới) các route đã khai báo:

import { BrowserRouter as Router, Route } from "react-router-dom";

export default function App() {
  return (
    <Router>
      <Navbar />
      <Route path="/" component={Home} />
      <Route path="/about" component={About} />
    </Router>
  );
}

function Navbar() {
  // visible on every page
  return <>navbar</>
}

function Home() {
  return <>home</>;
}

function About() {
  return <>about</>;
}

Switch Component

Khi chúng ta bắt đầu thêm nhiều routes, chúng ta sẽ dễ nhận thấy vấn đề như sau :

Khi chúng ta có một route cho trang Home và trang About. Mặc dù chúng ta chỉ định hai path khác nhau, '/' và '/ about', nhưng khi chúng ta truy cập trang About, chúng ta sẽ thấy cả trang Home và các thành phần trang About.

Và để giải quyết vấn đề này, ta sẽ sử dụng prop exact trên Home route để đảm bảo rằng Router của chúng ta khớp chính xác với path '/' thay vì '/ about':

import { BrowserRouter as Router, Switch, Route } from "react-router-dom";

export default function App() {
  return (
    <Router>
      <Navbar />
      <Switch>
        <Route exact path="/" component={Home} />
        <Route path="/about" component={About} />
      </Switch>
    </Router>
  );
}

Ngoài ra, nếu bạn có nhiều route thì bạn nên sử dụng component Switch .Vì Switch component sẽ check qua tất cả các Route con và nó sẽ hiển thị Route đầu tiên có path khớp với url hiện tại.

Component Switch sẽ được đặt trong Router và chúng ta có thể đặt tất cả các Routes của mình bên trong nó.

import { BrowserRouter as Router, Switch, Route } from "react-router-dom";

export default function App() {
  return (
    <Router>
      <Navbar />
      <Switch>
        <Route exact path="/" component={Home} />
        <Route path="/about" component={About} />
      </Switch>
    </Router>
  );
}

404 Route

Nếu user truy cập 1 path không tồn tại trong ứng dụng của chúng ta, thì họ sẽ không thấy gì(trang trắng) nếu chúng ta không có một route tương ứng với điều đó.

Vậy nếu user cố gắng truy cập một trang mà chúng ta không có route xác định, thì chúng ta có thể tạo một route và đặt path một dấu * . Cụ thể như sau :

import { BrowserRouter as Router, Switch, Route } from "react-router-dom";

import { BrowserRouter as Router, Switch, Route } from "react-router-dom";

export default function App() {
  return (
    <Router>
      <Navbar />
      <Switch>
        <Route path="/" component={Home} />
        <Route path="/about" component={About} />
        <Route path="*" component={NotFound} />
      </Switch>
    </Router>
  );
}

function NotFound() {
  return <>You have landed on a page that doesn't exist</>;
}

Với đoạn code trên, khi user để truy cập một trang không tồn tại thì sẽ load NotFound component để thông báo cho người dùng biết họ đã truy cập vào trang không tồn tại.

Link Component

Giả sử rằng trong NavBar, chúng ta muốn tạo một số links để user có thể di chuyển đến trang khác trong ứng dụng dễ dàng hơn thay vì phải thay đổi url theo cách thủ công trên trình duyệt.

Và ta có thể làm như vậy với một component đặc biệt khác của React Router DOM là Link component.

Với to prop, chúng ta có thể chỉ định link điều hướng người dùng.

Trong trường hợp này, chúng ta có link đến trang Home và About

import { BrowserRouter as Router, Switch, Route, Link } from "react-router-dom";

export default function App() {
  return (
    <Router>
      <Navbar />
      <Switch>
        <Route path="/" component={Home} />
        <Route path="/about" component={About} />
      </Switch>
    </Router>
  );
}

function Navbar() {
  return (
    <nav>
      <Link to="/">Home</Link>
      <Link to="/about">About</Link>
    </nav>
  )
}

Ngoài ra, Link component cũng cho phép chúng ta sử dụng inline styles giống như component React thông thường khác.

NavLink Component

React Router DOM cũng cung cấp cho chúng ta một component NavLink rất hữu ích trong trường hợp chúng ta muốn áp dụng một số style đặc biệt.

Ví dụ nếu người dùng đang ở trên trang Home, chúng ta có thể cho họ biết bằng cách sử dụng activeStyle prop để làm cho liên kết sẽ được in đậm và có màu đỏ.

import {
  BrowserRouter as Router,
  Switch,
  Route,
  NavLink
} from "react-router-dom";

export default function App() {
  return (
    <Router>
      <Navbar />
      <Switch>
        <Route path="/" component={Home} />
        <Route path="/about" component={About} />
      </Switch>
    </Router>
  );
}

function Navbar() {
  return (
    <nav>
      <NavLink
        activeStyle={{
          fontWeight: "bold",
          color: "red"
        }}
        to="/"
      >
        Home
      </NavLink>
      <NavLink activeClassName="active" to="/about">
        About
      </NavLink>
    </nav>
  );
}

Ngoài ra, nếu không muốn sử dụng inline styles khi dùng activeStyle thì bạn có thể sử dụng activeClassName prop thay thế.

Redirect Component

Một component rất hữu ích khác mà React Router DOM cung cấp làRedirect Component

Đúng như tên gọi thì Redirect component đơn giản là thực hiện chức năng chuyển hướng người dùng.

Giả sử chúng ta có 1 private route có điều kiện nếu user chưa authenticated thì chúng ta muốn chuyển hướng họ trở lại trang đăng nhập.

import {
  BrowserRouter as Router,
  Switch,
  Route,
  Redirect
} from "react-router-dom";

export default function App() {
  return (
    <Router>
      <Switch>
        <Route exact path="/" component={Home} />
        <PrivateRoute path="/hidden" component={Hidden} />
      </Switch>
    </Router>
  );
}

function PrivateRoute({ component: Component, ...rest }) {
  // useAuth is some custom hook to get the current user's auth state
  const isAuth = useAuth();

  return (
    <Route
      {...rest}
      render={(props) =>
        isAuth ? <Component {...props} /> : <Redirect to="/" />
      }
    />
  );
}
    
function Home() {
  return <>home</>;
}

function Hidden() {
  return <>hidden</>;
}

Lời kết

Phần tiếp theo chúng ta sẽ tìm hiểu sâu về những hook như useHistory ,useLocation , useParams,....

Cảm ơn mọi người đã đọc bài viết 😃

Mọi người có thể đọc bài gốc của tác giả ở đây

https://dev.to/reedbarger/the-react-router-cheatsheet-everything-you-should-know-23h5


All Rights Reserved