Tìm hiểu React Router 2021 - Phần 1
Bài đăng này đã không được cập nhật trong 2 năm
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ạirouters
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à path
và component
(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 Router
như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