😍React router dom (Full)

Hiện tại có những phiền bản phù hợp cho class, function nên phải chọn phù hợp phiên bản

v5 phù hợp với class, v6, v7 không phù hợp với class

package.json

{
  "name": "test",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^5.14.1",
    "@testing-library/react": "^13.0.0",
    "@testing-library/user-event": "^13.2.1",
    "@types/jest": "^27.0.1",
    "@types/node": "^16.7.13",
    "@types/react": "^18.0.0",
    "@types/react-dom": "^18.0.0",
    "axios": "^1.7.9",
    "react": "^19.0.0",
    "react-dom": "^19.0.0",
    "react-render-html": "^0.6.0",
    "react-router-dom": "5.2.0",
    "react-scripts": "5.0.1",
    "typescript": "^4.4.2",
    "web-vitals": "^2.1.0"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

src\App.tsx

import { Component, ReactNode } from 'react';
import { BrowserRouter, Route, Switch } from 'react-router-dom';
import routes from './routes';
import Menu from './components/Menu';
class App extends Component<any, any> {
  showContentMenus = (routes: any) => {
    var result = null;
    if (routes.length > 0) {
      result = routes.map((route: any, index: any) => {
        return (
          <Route key={index} path={route.path} exact={route.exact} component={route.main}></Route>
        )
      });
    }
    return result;
  }
  render(): ReactNode {
    return (
      <BrowserRouter>
        <div className="App">
          <Menu />
          <Switch>
            {this.showContentMenus(routes)}
          </Switch>
        </div>
      </BrowserRouter>
    );
  }
}
export default App;

src\routes.tsx

import Home from "./components/Home";
import About from "./components/About";
import Contact from "./components/Contact";
import Products from "./components/Products";
import Login from "./components/Login";
import NotFound from "./components/NotFound";
import Product from "./components/Product";
const routes = [
  {
    path: "/",
    exact: true,
    main:() =>  <Home />
  },
  {
    path: "/about",
    exact: true,
    main:() =>  <About />
  },
  {
    path: "/contact",
    exact: true,
    main:() =>  <Contact />
  },
  {
    path: "/products",
    exact: true,
    main: ( {match, location}:any) => <Products location={location} match={match}  />
  },
  {
    path: "/products/:slug",
    exact: true,
    main: ( {match, location}:any) => <Product location={location} match={match}  />
  },
  {
    path: "/login",
    exact: true,
    main:() =>  <Login />
  },
  {
    path: "*",
    exact: false,
    main:() =>  <NotFound />
  },
];
export default routes;

src\components\About.tsx

import React, { Component } from 'react';
class About extends Component {
  render() {
    return (
      <div className='about'>
        About
      </div>
    );
  }
}
export default About;

src\components\Contact.tsx

import React, { Component } from 'react';
class Contact extends Component {
  render() {
    return (
      <div>
        Contact
      </div>
    );
  }
}
export default Contact;

src\components\Home.tsx

import React, { Component } from 'react';
class Home extends Component {
  render() {
    return (
      <div>
        Home
      </div>
    );
  }
}
export default Home;

src\components\Login.tsx

import React, { Component } from 'react';
class Login extends Component {
  render() {
    return (
      <div>
        Login
      </div>
    );
  }
}
export default Login;

src\components\Menu.tsx

import React, { Component } from 'react';
import { Route, NavLink } from 'react-router-dom';
var menus = [
  {
    to: '/',
    label: 'Trang chủ',
    exact: true
  },
  {
    to: '/about',
    label: 'Giới thiệu',
    exact: false
  },
  {
    to: '/contact',
    label: 'Liên hệ',
    exact: false
  },
  {
    to: '/products',
    label: 'Danh sách sản phẩm',
    exact: false
  },
  {
    to: '/login',
    label: 'Đăng nhập',
    exact: false
  }
];
class Menu extends Component {
  showMenus = (menus: any) => {
    var result = null;
    if (menus.length > 0) {
      result = menus.map((menu: any, index: any) => {
        return (
          <NavLink className="mx-1" key={index} to={menu.to}>{menu.label}</NavLink>
        );
      });
    }
    return result;
  }
  render() {
    return (
      <div className='menu'>
        {this.showMenus(menus)}
      </div>
    );
  }
}
export default Menu;

src\components\NotFound.tsx

import React, { Component } from 'react';
class NotFound extends Component {
  render() {
    return (
      <div>
        NotFound
      </div>
    );
  }
}
export default NotFound;

src\components\Product.tsx

import React, { Component } from 'react';
class Product extends Component<any,any> {
  render() {
    var {match} = this.props;
    return (
      <div className="Product text-center">
        <h1>Trang chi tiết sản phẩm: {match.params.slug}</h1>
      </div>
    );
  }
}
export default Product;

src\components\Products.tsx

import React, { Component } from 'react';
import { BrowserRouter, NavLink, Route, Switch } from 'react-router-dom';
import Product from './../components/Product';
class Products extends Component<any, any> {
  render() {
    var products = [
      {
        id: 1,
        name: "Iphone 6 Plus",
        slug: 'iphone6plus',
        price: 6000000
      },
      {
        id: 2,
        name: "Iphone 7 Plus",
        slug: 'iphone7plus',
        price: 7000000
      },
      {
        id: 3,
        name: "Iphone 8 Plus",
        slug: 'iphone8plus',
        price: 8000000
      }
    ];
    var {match} = this.props;
    var {url} = match;
    var result = products.map((product, index) => {
      return (
        <NavLink key={index} to={`${url}/${product.slug}`}>
          <li className="list-group-item">
            {product.id} - {product.name} - {product.price}
          </li>
        </NavLink>
      )
    });
    return (
        <div>
          <h2>Products</h2>
          <p>{result}</p>
        </div>
    );
  }
}
export default Products;

V6, V7 cách khai báo sử dụng có hơi khác đọc bài dưới để biết thêm cách sử dụng function element trong class element

package.json

{
  "name": "test",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^5.14.1",
    "@testing-library/react": "^13.0.0",
    "@testing-library/user-event": "^13.2.1",
    "@types/jest": "^27.0.1",
    "@types/node": "^16.7.13",
    "@types/react": "^18.0.0",
    "@types/react-dom": "^18.0.0",
    "axios": "^1.7.9",
    "react": "^19.0.0",
    "react-dom": "^19.0.0",
    "react-render-html": "^0.6.0",
    "react-router-dom": "6",
    "react-scripts": "5.0.1",
    "typescript": "^4.4.2",
    "web-vitals": "^2.1.0"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

src\routes.tsx

import Home from "./components/Home";
import About from "./components/About";
import Contact from "./components/Contact";
import Products from "./components/Products";
import Login from "./components/Login";
import NotFound from "./components/NotFound";
import Product from "./components/Product";
const routes = [
  {
    path: "/",
    exact: true,
    main: () => <Home />
  },
  {
    path: "about",
    exact: true,
    main: <About />
  },
  {
    path: "contact",
    exact: true,
    main: <Contact />
  },
  {
    path: "products",
    exact: true,
    main: <Products />
  },
  {
    path: "products/:slug",
    exact: true,
    main: <Product />
  },
  {
    path: "/login",
    exact: true,
    main: <Login />
  },
  {
    path: "*",
    exact: false,
    main: <NotFound />
  },
];
export default routes;

src\index.tsx

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import "./index.css";
import reportWebVitals from './reportWebVitals';
const root = ReactDOM.createRoot(
  document.getElementById('root') as HTMLElement
);
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);
reportWebVitals();

src\components\Product.tsx

import { Component } from 'react';
import { useParams,useNavigate} from 'react-router-dom';
class Product extends Component<any,any> {
  render() {
    console.log(this.props);
    var {params: {slug}} = this.props;
    return (
      <div className="Product text-center">
        <h1>Trang chi tiết sản phẩm: {slug} </h1>
      </div>
    );
  }
}
export default (props:any) => (
  <Product
      {...props}
      params={useParams()}
      navi={useNavigate()}
  />
);

src\components\Products.tsx

import React, { Component } from 'react';
import { BrowserRouter, NavLink, Route, Routes,useParams,useLocation } from 'react-router-dom';
import Product from './../components/Product';
function withParams(Component:any) {
  return (props:any) => <Component {...props} location={useLocation()} />;
}
class Products extends Component<any, any> {
  render() {
    var products = [
      {
        id: 1,
        name: "Iphone 6 Plus",
        slug: 'iphone6plus',
        price: 6000000
      },
      {
        id: 2,
        name: "Iphone 7 Plus",
        slug: 'iphone7plus',
        price: 7000000
      },
      {
        id: 3,
        name: "Iphone 8 Plus",
        slug: 'iphone8plus',
        price: 8000001
      }
    ];
    var {location: {pathname:url}} = this.props;
    console.log(this.props);
    var result = products.map((product, index) => {
      return (
        <NavLink key={index} to={`${url}/${product.slug}`}>
          <li className="list-group-item">
            {product.id} - {product.name} - {product.price}
          </li>
        </NavLink>
      )
    });
    return (
        <div>
          <h2>Products</h2>
          {result}
        </div>
    );
  }
}
export default withParams(Products);

src\components\Home.tsx

import React, { Component } from 'react';
import { Link } from "react-router-dom";
class Home extends Component {
  render() {
    return (
      <div>
        <h1>This is the home page</h1>
        <p><Link to="about">Click to view our about page</Link></p>
        <p><Link to="contact">Click to view our contact page</Link></p>
      </div>
    );
  }
}
export default Home;

Hoặc ví dụ này cũng đã triển khai trên class

src\routes\index.tsx

import HomePage from "../Pages/HomePage";
import ProductListPage from "../Pages/ProductListPage";
const routes = [
  {
    path: "/",
    exact: true,
    main: () => <HomePage />
  },
  {
    path: '/product-list',
    exact: false,
    main: () => <ProductListPage />
  }
];
export default routes;

src\Pages\HomePage.tsx

import React, { Component } from 'react';
class HomePage extends Component {
  render() {
    return (
      <div>
        Home
      </div>
    );
  }
}
export default HomePage;

src\Pages\ProductListPage.tsx

import React, { Component } from 'react';
class ProductListPage extends Component {
  render() {
    return (
      <div>
        ProductListPage
      </div>
    );
  }
}
export default ProductListPage;

Last updated

Was this helpful?