Bài 13: ReactJS - Router - Học ReactJS Full Đầy Đủ Nhất

Đăng bởi: Admin | Lượt xem: 4486 | Chuyên mục: Javascript


1. Định nghĩa React-Router :

React-Router là một thư viện định tuyến (routing) tiêu chuẩn trong React. Nó giữ cho giao diện của ứng dụng đồng bộ với URL trên trình duyệt. React-Router cho phép bạn định tuyến "luồng dữ liệu" (data flow) trong ứng dụng của bạn một cách rõ ràng. Nó tương đương với sự khẳng định, nếu bạn có URL này, nó sẽ tương đương với Route này, và giao diện tương ứng.Ý tưởng của Router (bộ định tuyến) thực sự rất hữu ích vì bản chất bạn đang làm việc với React, một thư viện Javascript để lập trình các ứng dụng một trang ( Single Page Application). Để phát triển ứng dụng React bạn phải viết rất nhiều Component nhưng lại chỉ cần một tập tin duy nhất để phục vụ người dùng, đó là index.html (Cơ bản là thế).
React Router giúp bạn định nghĩa ra các URL động, và lựa chọn Component phù hợp để hiển thị trên trình duyệt người dùng ứng với từng URL.Để làm việc với router thì đầu tiên bạn cần cài đặt thư viên của nó, cú pháp như sau :
npm install react-router-dom --save

2. Các thành phần trong React-Router

a- BrowserRouter vs HashRouter
  • React-Router cung cấp cho chúng 2 thành phần hay sử dụng đó là BrowserRouter & HashRouter. Hai thành phần này khác nhau ở kiểu URL mà chúng sẽ tạo ra và đồng bộ.
  • BrowserRouter: Được sử dụng phổ biến hơn, nó sử dụng History API có trong HTML5 để theo dõi lịch sử bộ định tuyến của bạn.
  • HashRouter: Sử dụng hash của URL (window.location.hash) để ghi nhớ mọi thứ.
import { BrowserRouter as Router, Route, Link, NavLink } from "react-router-dom";
b - Route :
Route: Định nghĩa một ánh xạ (mapping) giữa một URL và một Component. Điều đó có nghĩa là khi người dùng truy cập theo một URL trên trình duyệt, một Component tương ứng sẽ được rendertrên giao diện.
<Router>
    <div className="App">
        <Route path="/" exact component={Home} />
        <Route path="/about" component={About} />
        <Route path="/contact" component={Contact} />
        <Route component={NotFound}/>
    </div>
</Router>
Trong đó :
  • path: Là đường dẫn trên URL.
  • exact: Giúp cho route này này chỉ hoạt động nếu URL trên trình duyệt phù hợp tuyệt đối với giá trị của thuộc tính path của nó.
  • component: Là component sẽ đươc load ra tương ứng với Route đó.
<BrowserRouter>
  <Route exact path="/" component={Home}/>
  <Route path="/about" component={About}/>
  <Route path="/topics" component={Topics}/>
</BrowserRouter>
 
 
<HashRouter>
  <Route exact path="/" component={Home}/>
  <Route path="/about" component={About}/>
  <Route path="/topics" component={Topics}/>
</HashRouter>
<BrowserRouter>
    ...
    <Route path="/about" component={About}/>
    ...
</BrowserRouter>

http://example.com/about                      ==> OK Work!
http://example.com/about#somthing             ==> OK Work!
http://example.com/about/something            ==> OK Work!
http://example.com/about/a/b                  ==> OK Work!

-------------------

http://example.com/something/about            ==> Not Work!
http://example.com/something/about#something  ==> Not Work!
http://example.com/something/about/something  ==> Not Work!

<HashRouter>
    ...
    <Route path="/about" component={About}/>
    ...
</HashRouter>

http://example.com#/about                      ==> OK Work!
http://example.com#/about/somthing             ==> OK Work!

----------------

http://example.com/something             ==> Not Work!
http://example.com/something#/about      ==> Not Work!
<BrowserRouter>
    ...
    <Route exact path="/about" component={About}/>
    ...
</BrowserRouter>


http://example.com/about                      ==> OK Work!
http://example.com/about#somthing             ==> OK Work!

-------------

http://example.com/about/something            ==> Not Work!
http://example.com/about/a/b                  ==> Not Work!

http://example.com/something/about            ==> Not Work!
http://example.com/something/about#something  ==> Not Work!
http://example.com/something/about/something  ==> Not Work!

<HashRouter>
    ...
    <Route exact path="/about" component={About}/>
    ...
</HashRouter>

http://example.com#/about                      ==> OK Work!

----------------

http://example.com#/about/somthing             ==>  Not Work!
http://example.com/something                   ==> Not Work!
http://example.com/something#/about            ==> Not Work!
c - Link :
Trong HTML thì cặp thẻ để chuyển hướng đó là thẻ <a></a> thì trong react chúng ta sẽ dử dụng cặp thẻ <Link></Link> được import từ React-Router.
<Link to="/about">About</Link>
trong đó:
  • to: Giống như thuộc tính href trong thẻ a.
d - NavLink :
NavLink thì rất giống với Link về cách sử dụng, nhưng NavLink tốt hơn vì nó hỗ trợ thêm một số thuộc tính như là activeClassName và activeStyle 2 thuộc tính này giúp cho khi mà nó trùng khớp thì nó sẽ được active lên và chúng ta có thể style cho nó.
<NavLink exact activeStyle={{
    backgroundColor : 'white',
    color : 'red'
}} to="/" className="my-link">Trang Chu</NavLink>
e - Custom Link :
ở trên ta có thẻ NavLink giúp chúng ta có thêm một thuộc tính nhưng giả sử khi bạn không muốn activeClassName hoặc activeStyle tại thẻ NavLink mà nó lại nằm ở một thẻ bao nó ví dụ như thẻ div hay thẻ li thì sao? sau đây mình sẽ custom lại để có thể sử dụng các class hoặc style ở thẻ bao ngoài của nó.
const MenuLink = ({
    label, // nội dung trong thẻ
    to, // giống như href trong thẻ a
    activeOnlyWhenExact
}) => {
    return (
        <Route 
            path={to}
            exact={activeOnlyWhenExact}
            children={ ({ match }) => { //match la doi tuong xac dinh su trung khop cua URL
                var active = match ? 'active abc' : '';

                return (
                    <li className={`my-li ${active}`}>
                        <Link  to={to} className="my-link">{label}</Link>
                    </li>
                );
            }}
        />
    );
}
f - Đối tượng Match :
Khi bạn muốn lấy một số thông tin ở trên URL thì bạn có thể dùng đối tượng match để lấy dữ liệu về. Tại cấu hình Router ta chỉ cần truyền thêm đối tượng match vào component mà cần sử dụng đối tượng match
{
        path : '/products',
        exact : false,
        main : ({match}) => <Products match={match} />
    }
Khiconsole.log(match)ta sẽ có kết quả như sau.
Trong đối tượng params sẽ chứa các tham số mà ta truyền trên URL.
i - Đối tượng prompt - Xác nhận trước khi chuyển trang
Giả sử khi bạn đang nhập liệu ở form nào đó mà không may click nút back hay chuyển trang thì thôi xong dữ liệu bạn nhập sẽ mất hết để khác phục điều đó ta có đối tượng prompt nó sẽ giúp chúng ta trước khi back hay chuyển trang nó sẽ xác nhận xem là chúng ta có chắc chắn muốn back hay chuyển trang không!Khi muốn sử dụng đối tượng prompt thì chúng ta chỉ cần import nó từ react-router
import {Prompt} from 'react-router-dom';

<Prompt 
    when={true} // true | false
    message={ (location) => (`Ban chac chan muon di den ${location.pathname}`) }
/>
k - Redirect :
  • Chức năng dùng để chuyển trang.
  • Có thể truy xuất thông tin trang trước đó thông qua đối tượng location. Để sử dụng Redirect ta chỉ cần import nó từ react-router.
import { Redirect } from 'react-router-dom';
Khi bạn muốn sử dụng location thì tại cấu hình Router ta chỉ cần truyền thêm đối tượng location vào component mà cần sử dụng đối tượng location.
{
    path : '/login',
    exact : false,
    main : ({location}) => <Login location={location} />
}

3. Các ví dụ :

ví dụ 1 :Trước hết bạn cần cài đặt công cụ create-react-app,(ở các bài trước đã cài đặt) và tạo một dự án React với tên react-router-basic-app:
# Create project named 'react-router-basic-app':
 
create-react-app react-router-basic-app
Xóa hết nội dung của 2 tập tinApp.css & App.js, chúng ta sẽ viết code cho 2 tập tin này.App.css 
.main-route-place {
  border: 1px solid  #bb8fce;
  margin:3px;
  padding: 5px;
}
 
.secondary-route-place {
  border: 1px solid #a2d9ce;
  margin: 5px;
  padding: 5px;
}
App.js
import React from "react";
import { BrowserRouter, Route, Link } from "react-router-dom";
 
import './App.css';
 
class App extends React.Component {
 
  render()  {
    return  (
      <BrowserRouter>
        <div>
          <ul>
            <li>
              <Link to="/">Home</Link>
            </li>
            <li>
              <Link to="/about">About</Link>
            </li>
            <li>
              <Link to="/topics">Topics</Link>
            </li>
          </ul>
 
          <hr />
          <div className="main-route-place">
            <Route exact path="/" component={Home} />
            <Route path="/about" component={About} />
            <Route path="/topics" component={Topics} />
          </div>
        </div>
      </BrowserRouter>
    );
  }
 
}
 
class Home extends React.Component {
 
  render()  {
    return (
      <div>
        <h2>Home</h2>
      </div>
    );
  }
}
 
class About  extends React.Component {
  render() {
    return (
      <div>
        <h2>About</h2>
      </div>
    );
  }
}
 
class Topics extends React.Component {
  render( ) {
    return (
      <div>
        <h2>Topics</h2>
        <ul>
          <li>
            <Link to={`${this.props.match.url}/rendering`}>
              Rendering with React
            </Link>
          </li>
          <li>
            <Link to={`${this.props.match.url}/components`}>Components</Link>
          </li>
          <li>
            <Link to={`${this.props.match.url}/props-v-state`}>
              Props v. State
            </Link>
          </li>
        </ul>
 
        <div className="secondary-route-place">
          <Route
            path={`${this.props.match.url}/:topicId`}
            component={Topic} />
          <Route
            exact
            path={this.props.match.url}
            render={() =>
              <h3>
                Please select a topic.
              </h3>
            }
            />
        </div>
      </div>
    );
  }
}
 
class Topic extends React.Component {
  render()  {
    return (
      <div>
        <h3>
          {this.props.match.params.topicId}
        </h3>
      </div>
    );
  }
}
 
export default App;
index.html 
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="theme-color" content="#000000">
  
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json">
    <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
    
    <title>React App</title>
  </head>
  <body>
    <noscript>
      You need to enable JavaScript to run this app.
    </noscript>
    <div id="root"></div>
     
  </body>
</html>
Chạy ứng dụng của xem kết quả trên trình duyệt:
npm start
Trên đây là các kiến thức mà mình tìm hiểu được về các thành phần trong react-router, rất mong được sự góp ý của mọi người. Cảm ơn mọi người đã theo dõi .
Bài tiếp theo: ReactJS - Khái niệm Flux >>
vncoder logo

Theo dõi VnCoder trên Facebook, để cập nhật những bài viết, tin tức và khoá học mới nhất!