Tìm hiểu về ReactJS Router với một ví dụ cơ bản (NodeJS)

Xem thêm các chuyên mục:

1- React Router là gì?

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 (tuyến đường) này, và giao diện sẽ thế này!
Ý 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.

<BrowserRouter> vs <HashRouter>

React Router cung cấp cho bạn 2 thành phần 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>
http://example.com/about

// <HashRouter>
http://example.com/#/about
<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. Trong khi đó <HashRouter> sử dụng hash của URL ( window.location.hash) để ghi nhớ mọi thứ. Nếu bạn có ý định hỗ trợ các trình duyệt cũ, bạn nên gắn bó với <HashRouter>, hoặc bạn muốn tạo một ứng dụng React sử dụng Router ở phía client thì <HashRouter> là lựa chọn hợp lý.

<Route>

Thành phần <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 render trên giao diện.
<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>
 
Thuộc tính exact được sử dụng trong <Route> để nói rằng <Route> 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ó.

<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!

2- Tạo dự án và cài đặt thư viện

Trước hết bạn cần cài đặt công cụ create-react-app, và tạo một dự án React với tên react-router-basic-app:
# Install tool:

npm install -g create-react-app

# Create project named 'react-router-basic-app':

create-react-app react-router-basic-app

 
Project của bạn đã được tạo ra:
Tiếp theo, CD vào project vừa được tạo ra và thực thi lệnh dưới đây để cài đặt thư viện react-router-dom vào cho project của bạn:
# CD to your project

cd react-router-basic-app

# Install react-router-dom library:

npm install --save react-router-dom
 
Mở project của bạn trên một trình soạn thảo nào đó mà bạn quen thuộc (Chẳng hạn Atom). Mở tập tin package.json, bạn sẽ thấy thư viện react-router-dom đã được thêm vào dự án của bạn.
Khởi động ứng dụng của bạn:
# Start App

npm start

3- Viết code

Xóa hết nội dung của 2 tập tin App.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;
Không cần thay đổi gì với 2 tập tin index.js & index.html:
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';

ReactDOM.render(<App />, document.getElementById('root'));
registerServiceWorker();
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:

Xem thêm các chuyên mục: