hocvietcode.com
  • Trang chủ
  • Học lập trình
    • Lập trình C/C++
    • Lập trình HTML
    • Lập trình Javascript
      • Javascript cơ bản
      • ReactJS framework
      • AngularJS framework
      • Typescript cơ bản
      • Angular
    • Lập trình Mobile
      • Lập Trình Dart Cơ Bản
        • Dart Flutter Framework
    • Cơ sở dữ liệu
      • MySQL – MariaDB
      • Micrsoft SQL Server
      • Extensible Markup Language (XML)
      • JSON
    • Lập trình PHP
      • Lập trình PHP cơ bản
      • Laravel Framework
    • Lập trình Java
      • Java Cơ bản
    • Cấu trúc dữ liệu và giải thuật
    • Lập Trình C# Cơ Bản
    • Machine Learning
  • WORDPRESS
    • WordPress cơ bản
    • WordPress nâng cao
    • Chia sẻ WordPress
  • Kiến thức hệ thống
    • Microsoft Azure
    • Docker
    • Linux
  • Chia sẻ IT
    • Tin học văn phòng
      • Microsoft Word
      • Microsoft Excel
    • Marketing
      • Google Adwords
      • Facebook Ads
      • Kiến thức khác
    • Chia sẻ phần mềm
    • Review công nghệ
    • Công cụ – tiện ích
      • Kiểm tra bàn phím online
      • Kiểm tra webcam online
Đăng nhập
  • Đăng nhập / Đăng ký

Please enter key search to display results.

Home
  • ReactJS
Tạo Wrapper Component trong React với props

Tạo Wrapper Component trong React với props

  • 26-09-2022
  • Toanngo92
  • 0 Comments

Để hiểu bài viết này, hãy xem kĩ lại bài viết giới thiệu props trong ReactJS và tùy chỉnh thành phần (component) với props trước để đảm bảo bạn đã hiểu rõ về component. Trong bài viết này, chúng ta sẽ vẫn tiếp tục sử dụng dữ liệu mẫu và code mẫu của bài trước để làm ví dụ.

Mục lục

  • Tạo Wrapper Component
  • Truyền dữ liệu (pass data) thông qua props
  • Tạo Wrapper Component với children
  • Truyền Component như là Props

Tạo Wrapper Component

Nội dung file App.js

import './App.css';
import data from './data/data';
import ProductComp from './components/product/ProductComponent';

const App = () => {
  return (
    <div className='container'>
      <table>
        <thead>
          <tr>
            <th>ID</th>
            <th>Product</th>
            <th>Type</th>
            <th>PPU</th>
          </tr>
        </thead>
        <tbody>
          {data.map((item) => {
            return (<ProductComp key={item.id} id={item.id} name={item.name} type={item.type} ppu={item.ppu} batters={item.batters} topping={item.topping} />)
          })}
        </tbody>
      </table>
    </div>
  )

}

export default App;

Vẫn sử dụng file theo cấu trúc data/data.js như sau:

const data = [
	{
		"id": "0001",
		"type": "donut",
		"name": "Cake",
		"ppu": 0.55,
		"batters":
			{
				"batter":
					[
						{ "id": "1001", "type": "Regular" },
						{ "id": "1002", "type": "Chocolate" },
						{ "id": "1003", "type": "Blueberry" },
						{ "id": "1004", "type": "Devil's Food" }
					]
			},
		"topping":
			[
				{ "id": "5001", "type": "None" },
				{ "id": "5002", "type": "Glazed" },
				{ "id": "5005", "type": "Sugar" },
				{ "id": "5007", "type": "Powdered Sugar" },
				{ "id": "5006", "type": "Chocolate with Sprinkles" },
				{ "id": "5003", "type": "Chocolate" },
				{ "id": "5004", "type": "Maple" }
			]
	},
	{
		"id": "0002",
		"type": "donut",
		"name": "Raised",
		"ppu": 0.55,
		"batters":
			{
				"batter":
					[
						{ "id": "1001", "type": "Regular" }
					]
			},
		"topping":
			[
				{ "id": "5001", "type": "None" },
				{ "id": "5002", "type": "Glazed" },
				{ "id": "5005", "type": "Sugar" },
				{ "id": "5003", "type": "Chocolate" },
				{ "id": "5004", "type": "Maple" }
			]
	},
	{
		"id": "0003",
		"type": "donut",
		"name": "Old Fashioned",
		"ppu": 0.55,
		"batters":
			{
				"batter":
					[
						{ "id": "1001", "type": "Regular" },
						{ "id": "1002", "type": "Chocolate" }
					]
			},
		"topping":
			[
				{ "id": "5001", "type": "None" },
				{ "id": "5002", "type": "Glazed" },
				{ "id": "5003", "type": "Chocolate" },
				{ "id": "5004", "type": "Maple" }
			]
	}
];

export default data

Nội dung file components/product/ProductComp.js như sau:

import PropTypes from 'prop-types'

console.log(PropTypes);

const ProductComp = ({id,name,type,ppu,batters,topping}) => {
    
    const showBatters = (event,batters) =>{
        let batterstr = '';
        batters.batter.forEach(((item) => {
            batterstr += item.type+ '\n';
        }));
        alert(batterstr);
    }

    const showTopping = (event,topping) =>{
        let toppingstr = '';
        topping.forEach(((item) => {
            toppingstr += item.type+ '\n';
        }));
        alert(toppingstr);
    }
    
    return (<tr>
        <td>{id}</td>
        <td>{name}</td>
        <td>{type}</td>
        <td>{ppu}</td>
        <td><button onClick={(event) => showBatters(event,batters)}>Show batters</button></td>
        <td><button onClick={(event) => showTopping(event,topping)}>Show topping</button></td>
        </tr>)
}

export default ProductComp

ProductComp.propTypes = {
    id: PropTypes.string.isRequired,
    name: PropTypes.string.isRequired,
    type: PropTypes.string.isRequired,
    ppu: PropTypes.number.isRequired,
 //   batters: PropTypes.objectOf(PropTypes.arrayOf(PropTypes.object)).isRequired,
    batters: PropTypes.shape(
        {
            batter : PropTypes.arrayOf(PropTypes.object)
        }
    ),
    topping: PropTypes.arrayOf(PropTypes.object),
    showBatters: PropTypes.func,
    showTopping: PropTypes.func
}

Khi bạn làm việc trên các dự án phức tạp hơn, dữ liệu của bạn sẽ đến từ nhiều nơi khác nhau hơn, chẳng hạn như API, localStorage hoặc tệp tĩnh. Tuy nhiên, quy trình sử dụng từng biến này sẽ tương tự nhau: gán dữ liệu cho một biến và lặp qua dữ liệu. Trong trường hợp này, dữ liệu là từ một tệp tĩnh, vì vậy bạn đang nhập trực tiếp vào một biến.

Trong đoạn mã này, bạn sử dụng phương thức .map () để lặp lại các ProductComp và hiển thị các prop. Lưu ý rằng bạn không phải sử dụng từng phần dữ liệu. Bạn cũng đang thêm một key riêng mà React sẽ sử dụng để theo dõi dữ liệu được ánh xạ. Cuối cùng, bạn đang bao bọc mã bằng một thẻ <tbody/>.

Ở ví dụ trên, chúng ta hiển thị nút và sẽ mở dialog box biểu diễn các dữ liệu phức tạp của ProductComp thông qua sự kiện onClick, bây giờ mình không muốn như vậy nữa mà sẽ hiển thị thẳng ra bên trong thẻ <td> đang bao bọc, vì vậy mình sẽ bắt đầu thao tác các bước như sau:

Tạo file components/product/BatterComponent.js:

import React from "react";
import PropTypes from 'prop-types'

const BatterComp = (batters) => {
    
    const batter = batters.batters.batter // array

    return (<ul>
        {batter.map((item) => {
            return <li key={item.id}><strong>Id:</strong><i>{item.id}</i><strong>Type</strong><i>{item.type}</i></li>
        })}
    </ul>)
}

export default BatterComp

BatterComp.propTypes = {
    batters: PropTypes.object
}

BatterComp.defaultProps = {

}

Tạo file components/product/ToppingComponent.js:

import React from "react";
import PropTypes from 'prop-types'

const ToppingComp = (topping) => {

    const toppingarr = topping.topping

    return (<ul>{
        toppingarr.map((item) => {
            return <li key={item.id}><strong>Id:</strong><i>{item.id}</i><strong>Type</strong><i>{item.type}</i></li>
        })
        }</ul>)
}

export default ToppingComp


ToppingComp.propTypes = {
    topping: PropTypes.array
}

ToppingComp.defaultProps = {

}

Sửa file components/product/ProductComponent.js:

import React from "react";
import PropTypes from 'prop-types'
import BatterComp from "./BatterComponent";
import ToppingComp from "./ToppingComponent";

const ProductComp = ({id,name,type,ppu,batters,topping}) => {
    

    const showTopping = (event,topping) =>{
        let toppingstr = '';
        topping.forEach(((item) => {
            toppingstr += item.type+ '\n';
        }));
        alert(toppingstr);
    }
    
    return (<tr>
        <td>{id}</td>
        <td>{name}</td>
        <td>{type}</td>
        <td>{ppu}</td>
        <td><BatterComp batters={batters} /></td>
        <td><ToppingComp topping={topping} /></td>
        </tr>)
}

export default ProductComp

ProductComp.propTypes = {
    id: PropTypes.string.isRequired,
    name: PropTypes.string.isRequired,
    type: PropTypes.string.isRequired,
    ppu: PropTypes.number.isRequired,
 //   batters: PropTypes.objectOf(PropTypes.arrayOf(PropTypes.object)).isRequired,
    batters: PropTypes.shape(
        {
            batter : PropTypes.arrayOf(PropTypes.object)
        }
    ),
    topping: PropTypes.arrayOf(PropTypes.object),
    showBatters: PropTypes.func,
    showTopping: PropTypes.func
}

ProductComp.defaultProps = {
    ppu: 0
}

Cấu trúc dự án và output:

Truyền dữ liệu (pass data) thông qua props

Chuyển thông tin chi tiết qua một thành phần với … prop

Các thành phần đang hoạt động tốt với nhau, nhưng có một chút kém hiệu quả trong ProductComp. Bạn đang lấy các thuộc tính batter và topping thông qua dữ liệu mẫu, nhưng bạn không sử dụng dữ liệu. Thay vào đó, bạn đang chuyển nó qua component. Điều này vốn dĩ không có gì sai cả — trên thực tế, tốt vấn đề là bạn sẽ truyền dữ liệu qua nhiều bước, khi làm điều này, bạn làm cho mã của mình khó bảo trì hơn. Bất cứ khi nào bạn muốn Truyền dữ liệu mới vào BatterComponent hoặc ToppingComponent, bạn cần cập nhật ba vị trí: App.js, nơi bạn lấy dữ liệu của dữ liệu mẫu chuyển các props, BatterComponent hoặc ToppingComponent, nơi sử dụng props và ProductComp, là nơi giống như nơi trung chuyển nằm giữa giữa.

Giải pháp tốt hơn là nên thu thập bất kỳ prop nào không sử dụng bên trong ProductComp và sau đó chuyển trực tiếp chúng đến BatterComponent hoặc ToppingComponent. Điều này cho bạn cơ hội thực hiện thay đổi đối với BatterComponent hoặc ToppingComponent mà không cần thay đổi thẻ ProductComp. Trên thực tế, ProductComp không cần biết bất kỳ điều gì về các props hoặc các PropTypes sẽ được đưa vào BatterComponent hoặc ToppingComponent.

Để làm điều đó, bạn sẽ sử dụng toán tử phần còn lại đối tượng. Toán tử này thu thập bất kỳ mục nào không được lấy ra trong quá trình destructure và lưu chúng vào một đối tượng mới.
Đây là một ví dụ đơn giản:

const topping = {
    "name": "topping",
    "toppingval" : [
        { "id": "5001", "type": "None" },
        { "id": "5002", "type": "Glazed" },
        { "id": "5005", "type": "Sugar" },
        { "id": "5007", "type": "Powdered Sugar" },
        { "id": "5006", "type": "Chocolate with Sprinkles" },
        { "id": "5003", "type": "Chocolate" },
        { "id": "5004", "type": "Maple" }
    ]    
}

const {name, ...props} = topping;

console.log(name)
console.log(props)

Với ví dụ trên, dữ liệu được log ra của bến name sẽ có giá trị là:

topping

Dữ liệu biến props có giá trị là:

{ "toppingval" : [
        { "id": "5001", "type": "None" },
        { "id": "5002", "type": "Glazed" },
        { "id": "5005", "type": "Sugar" },
        { "id": "5007", "type": "Powdered Sugar" },
        { "id": "5006", "type": "Chocolate with Sprinkles" },
        { "id": "5003", "type": "Chocolate" },
        { "id": "5004", "type": "Maple" }
    ]   }

Áp dụng vào trường hợp phía trên như sau:

Sửa file components/product/ProductComponent.js

import React from "react";
import PropTypes from 'prop-types'
import BatterComp from "./BatterComponent";
import ToppingComp from "./ToppingComponent";

const ProductComp = ({id,name,type,ppu,...props}) => {
    
    return (<tr>
        <td>{id}</td>
        <td>{name}</td>
        <td>{type}</td>
        <td>{ppu}</td>
        <td><BatterComp {...props} /></td>
        <td><ToppingComp {...props} /></td>
        </tr>)
}

export default ProductComp

ProductComp.propTypes = {
    id: PropTypes.string.isRequired,
    name: PropTypes.string.isRequired,
    type: PropTypes.string.isRequired,
    ppu: PropTypes.number.isRequired,
 //   batters: PropTypes.objectOf(PropTypes.arrayOf(PropTypes.object)).isRequired,
    batters: PropTypes.shape(
        {
            batter : PropTypes.arrayOf(PropTypes.object)
        }
    ),
    topping: PropTypes.arrayOf(PropTypes.object),
    showBatters: PropTypes.func,
    showTopping: PropTypes.func
}

ProductComp.defaultProps = {
    ppu: 0
}

Nếu muốn cấu trúc code rõ ràng hơn, có thể sửa biến topping và batters file BatterComponent hoặc ToppingComponent thành props, nếu muốn code rõ ràng hơn nữa, chúng ta có thể sử dụng destructure object trong biến hứng props từ BatterComponent và ToppingComponent, ví dụ với ToppingComponent

import React from "react";
import PropTypes from 'prop-types'

const ToppingComp = ({batters,topping}) => {

    const toppingarr = topping

    return (<ul>{
        toppingarr.map((item) => {
            return <li key={item.id}><strong>Id:</strong><i>{item.id}</i><strong>Type</strong><i>{item.type}</i></li>
        })
        }</ul>)
}

export default ToppingComp


ToppingComp.propTypes = {
    topping: PropTypes.array
}

ToppingComp.defaultProps = {

}

Trong bước này, bạn đã học cách tạo các wrapper component linh hoạt có thể lấy các prop không xác định và chuyển chúng vào các component lồng nhau bằng toán tử spread. Đây là một mẫu phổ biến sẽ cung cấp cho bạn sự linh hoạt cần thiết để tạo các component có trách nhiệm tập trung. Trong bước tiếp theo, chúng ta sẽ tạo các component có thể lấy các thành phần không xác định làm chỗ dựa bằng cách sử dụng khái niệm children prop được tích hợp sẵn.

Tạo Wrapper Component với children

Trong bước này, bạn sẽ tạo một wrapper component có thể lấy một nhóm component không xác định làm prop. Điều này sẽ cung cấp cho bạn khả năng lồng ghép các thành phần như HTML tiêu chuẩn và nó sẽ cung cấp cho bạn một mẫu để tạo các trình bao bọc có thể tái sử dụng, cho phép bạn tạo nhiều component khác nhau cần thiết kế chung nhưng cơ chế biểu diễn linh hoạt.
React cung cấp cho bạn một builtin prop có tên là child để thu thập bất kỳ component con nào. Sử dụng điều này làm cho việc tạo các component của trình bao bọc trở nên trực quan và dễ đọc.
Để bắt đầu, hãy tạo một thành phần mới có tên là ProductCompWrapper. Đây sẽ là một trình bao bọc
component để tạo ra một phong cách tiêu chuẩn cho bất kỳ ProductComponent mới nào.

Tạo file components/product/ProductCompWrapper.js

import React from "react";
import PropTypes from 'prop-types'

const ProductComWrapper = ({ children, title }) => {
    return (
        <tr title={title}>{children}</tr>
    )
}

export default ProductComWrapper

ProductComWrapper.propTypes = {
    children: PropTypes.oneOfType([
        PropTypes.arrayOf(PropTypes.element),
        PropTypes.element.isRequired
    ]),
    title: PropTypes.string.isRequired,
}

Không giống như một React Component, bạn không cần phải có một root Component duy nhất khi sử dụng child. Đó là lý do tại sao PropType cho ProductComWrapper nó có thể là một mảng các Component hoặc một Component đơn. Ngoài việc chuyển các child dưới dạng các component lồng nhau, bạn đang đặt cho ProductComWrapper một title.

Sửa file components/product/ProductComponent.js

import React from "react";
import PropTypes from 'prop-types'
import BatterComp from "./BatterComponent";
import ToppingComp from "./ToppingComponent";

const ProductComp = ({id,name,type,ppu,...props}) => {
    
    return (<>
        <td>{id}</td>
        <td>{name}</td>
        <td>{type}</td>
        <td>{ppu}</td>
        <td><BatterComp {...props} /></td>
        <td><ToppingComp {...props} /></td>
        </>)
}

export default ProductComp

ProductComp.propTypes = {
    id: PropTypes.string.isRequired,
    name: PropTypes.string.isRequired,
    type: PropTypes.string.isRequired,
    ppu: PropTypes.number.isRequired,
 //   batters: PropTypes.objectOf(PropTypes.arrayOf(PropTypes.object)).isRequired,
    batters: PropTypes.shape(
        {
            batter : PropTypes.arrayOf(PropTypes.object)
        }
    ),
    topping: PropTypes.arrayOf(PropTypes.object),
    showBatters: PropTypes.func,
    showTopping: PropTypes.func
}

ProductComp.defaultProps = {
    ppu: 0
}

Sửa file App.js

import './App.css';
import data from './data/data';
import ProductComp from './components/product/ProductComponent';
import ProductComWrapper from './components/product/ProductCompWrapper';

const App = () => {
  return (
    <div className='container'>
      <table>
        <thead>
          <tr>
            <th>ID</th>
            <th>Product</th>
            <th>Type</th>
            <th>PPU</th>
            <th>Batters</th>
            <th>Topping</th>
          </tr>
        </thead>
        <tbody>
          {data.map((item) => {
            return (<ProductComWrapper key={item.id} title="helleo"><ProductComp id={item.id} name={item.name} type={item.type} ppu={item.ppu} batters={item.batters} topping={item.topping} /></ProductComWrapper>)
          })}
        </tbody>
      </table>
    </div>
  )

}

export default App;

Bây giờ bạn có một component ProductComWrapper có thể sử dụng lại có thể lấy bất kỳ số lượng con lồng nhau nào. Ưu điểm chính của việc này là bạn có thể sử dụng lại ProductComWrapper với bất kỳ component tùy ý nào. Nếu bạn muốn tạo thẻ mô tả một Product với kiểu dữ liệu khác, bạn có thể làm điều đó bằng cách gói thông tin dữ liệu với component ProductComWrapper .
Nó thậm chí không cần phải liên quan gì cả: Nếu bạn muốn sử dụng lại thành phần ProductComWrapper trong một ứng dụng hoàn toàn khác liệt kê những thứ như âm nhạc hoặc dữ liệu tài khoản, bạn cũng có thể làm điều đó. Thành phần ProductComWrapper không quan tâm child là gì; bạn chỉ đang sử dụng lại phần tử wrapper.
Nhược điểm của việc sử dụng child là bạn chỉ có thể có một instance của child. Đôi khi, bạn sẽ muốn một thành phần có JSX tùy chỉnh ở nhiều nơi. May mắn thay, bạn có thể làm điều đó bằng cách chuyển các JSX và component React như là prop, mà chúng ta sẽ đề cập trong bước tiếp theo.

Truyền Component như là Props

Trong bước này, bạn sẽ sửa đổi component ProductComWrapper để lấy các component khác làm prop. Điều này sẽ cung cấp cho component của bạn sự linh hoạt tối đa để hiển thị các thành phần không xác định hoặc JSX ở nhiều vị trí trên toàn bộ trang.
Không giống như child, bạn chỉ có thể sử dụng một lần, bạn có thể có nhiều các component làm prop, mang lại cho wrapper component khả năng thích ứng với nhiều nhu cầu khác nhau trong khi vẫn duy trì giao diện và cấu trúc chuẩn.
Đến cuối bước này, bạn sẽ có một component có thể bao bọc các thành phần con và cũng hiển thị các thành phần khác trong ProductComWrapper . Mẫu này sẽ cung cấp cho bạn sự linh hoạt khi bạn cần tạo các component cần thông tin phức tạp hơn các chuỗi và số đơn giản.

Vì cấu trúc này dữ liệu khá phức tạp, nên mình sẽ thay đổi lại cấu trúc HTML từ dạng bảng thành flex-box và css cho nó.

Sửa file components/product/ProductCompWrapper.js

import React from "react";
import PropTypes from 'prop-types'

const ProductComWrapper = ({ children, details, title }) => {
    return (
        <div className="box-item" title={title}>
            {children}
            <span> {title}: {details}</span>
        </div>
    )
}

export default ProductComWrapper

ProductComWrapper.propTypes = {
    children: PropTypes.oneOfType([
        PropTypes.arrayOf(PropTypes.element),
        PropTypes.element.isRequired
    ]),
    title: PropTypes.string.isRequired,
    details: PropTypes.element,
}

ProductComWrapper.defaultProps = {
    details: null,
}

Prop details này sẽ cùng kiểu với child, nên là là optional. Để làm cho nó optional, bạn thêm một giá trị mặc định là null. Trong trường hợp này, nếu người dùng không chuyển thông tin chi tiết, thành phần sẽ vẫn có hiệu lực và sẽ không hiển thị thêm bất kỳ thứ gì.

Sửa lại cấu trúc cũ file App.js (không cần bọc ProductComWarpper bên ngooài):

import './App.css';
import data from './data/data';
import ProductComp from './components/product/ProductComponent';
import ProductComWrapper from './components/product/ProductCompWrapper';

const App = () => {


  // return (<></>)
  return (
    <div className='container'>
      <div className='box-wrapper'>
        <div className='box-top'>
          <div className='box-item'>
            <strong>ID</strong>
            <strong>Product</strong>
            <strong>Type</strong>
            <strong>PPU</strong>
            <strong>Batters</strong>
            <strong>Topping</strong>
            <strong>Detail</strong>
          </div>
        </div>
        <div className='box-bottom'>
          {data.map((item) => {
            return (<ProductComp id={item.id} name={item.name} type={item.type} ppu={item.ppu} batters={item.batters} topping={item.topping} />)
          })}
        </div>
      </div>
    </div>
  )

}

export default App;

Sửa file App.css

.box-item{
    display: flex;
    width: 1200px;
    margin: auto;
}
.box-item > strong,.box-item > span{
    border: 1px solid #e1e1e1;
    display: block;
    width: 14.2857%;
    padding: 5px;
    box-sizing: border-box;
}

.box-item ul {
    list-style: none;
    padding: 0px;
}

Sửa file components/product/ProductComponent.js

import React from "react";
import PropTypes from 'prop-types'
import BatterComp from "./BatterComponent";
import ToppingComp from "./ToppingComponent";
import ProductComWrapper from "./ProductCompWrapper";

const ProductComp = ({id,name,type,ppu,...props}) => {
    
    return (<ProductComWrapper className="data-box" title="Description" details={<>This is props passing by of ProductWarpper</>}>
        <span>{id}</span>
        <span>{name}</span>
        <span>{type}</span>
        <span>{ppu}</span>
        <span><BatterComp {...props} /></span>
        <span><ToppingComp {...props} /></span>
        </ProductComWrapper>)
}

export default ProductComp

ProductComp.propTypes = {
    id: PropTypes.string.isRequired,
    name: PropTypes.string.isRequired,
    type: PropTypes.string.isRequired,
    ppu: PropTypes.number.isRequired,
 //   batters: PropTypes.objectOf(PropTypes.arrayOf(PropTypes.object)).isRequired,
    batters: PropTypes.shape(
        {
            batter : PropTypes.arrayOf(PropTypes.object)
        }
    ),
    topping: PropTypes.arrayOf(PropTypes.object),
    showBatters: PropTypes.func,
    showTopping: PropTypes.func
}

ProductComp.defaultProps = {
    ppu: 0
}

Output:

Ở ví dụ phía trên, chúng ta thấy component ProductComp mặc dù là Component con đưược gọi thông qua {children} , nhưng nó lại có khả năng truyền props cho ProductCompWrapper là component cha sử dụng. Chúng ta hoàn toàn có thể tùy biến 1 trong 2 cách trên và dưới để mã nguồn linh hoạt, dễ bảo trì hơn.

Bài tập

Bài tập: Xây dựng Ứng dụng Quản lý Xe với ReactJS

Phần 1: Setup và Khởi tạo Dự án

Setup Project ReactJS

  1. Tạo một dự án ReactJS mới bằng cách sử dụng Create React App.
  2. Cấu hình dự án để sử dụng hooks nhằm quản lý state hiệu quả.

Tạo Component Khởi đầu

  1. Tạo một component App.js.
  2. Trong App.js, khởi tạo state bao gồm:
    • Một biến vehicles kiểu mảng chứa thông tin các xe với các thuộc tính:
      const [vehicles, setVehicles] = useState([
        { id: 1, name: 'Honda Civic', image: '/path/to/civic', status: 'available', price: 20 },
        { id: 2, name: 'Toyota Corolla', image: '/path/to/corolla', status: 'available', price: 25 },
        { id: 3, name: 'Tesla Model 3', image: '/path/to/tesla', status: 'available', price: 50 },
      ]);
      
    • Một biến rentedVehicles kiểu mảng để lưu danh sách xe đã thuê.
    • Một biến budget kiểu số để theo dõi ngân sách còn lại (khởi tạo là 500).

Phần 2: Hiển thị Danh sách Xe

Tạo Component Vehicle

  1. Tạo một component Vehicle.js.
  2. Component này nhận thông tin xe thông qua props và hiển thị:
    • Tên xe.
    • Hình ảnh.
    • Trạng thái (available/đã thuê).
    • Nút "Thuê xe".

Hiển thị Danh sách Xe

  1. Tạo một component VehicleList.js.
  2. Sử dụng hàm map để lặp qua danh sách trong biến vehicles và hiển thị mỗi xe bằng component Vehicle.

Hiển thị trên Trang chính

  1. Trong App.js, sử dụng component VehicleList để hiển thị danh sách xe.

Phần 3: Thuê Xe

Tạo Component RentVehicle

  1. Thêm xử lý sự kiện khi người dùng nhấn nút "Thuê xe":
    • Hiển thị alert "Xử lý thuê xe".
    • Viết thuật toán kiểm tra ngân sách:
      • Nếu ngân sách đủ, trừ đi giá thuê xe và cập nhật trạng thái xe thành "đã thuê".
      • Nếu không đủ ngân sách, hiển thị alert "Ngân sách không đủ để thuê xe này".
    • Nếu thuê thành công, hiển thị alert "Thuê thành công + Tên xe" và cập nhật xe vào danh sách rentedVehicles.

Cập nhật Danh sách Xe đã Thuê

  1. Sau khi thuê xe, cập nhật danh sách xe đã thuê hiển thị trên trang chính.

Phần 4: Xây dựng Garage

Tạo Component Garage

  1. Tạo một component Garage.js.
  2. Component này hiển thị danh sách các xe đã thuê.

Router và Chuyển đổi giữa các Trang

  1. Thiết lập router trong App.js:
    • Một route cho trang chính hiển thị tất cả xe (VehicleList).
    • Một route cho bộ sưu tập xe đã thuê (Garage).

 

Bài viết liên quan:

useMemo trong ReactJS
Định tuyến trong ứng dụng React với React Router
Giới thiệu Redux và quản lý state với Redux trong React
Gọi API trong React với useEffect Hook
Xử lý tải dữ liệu bất đồng bộ (Async Data Loading), lazyload trong React
Xử lý Form (biểu mẫu) trong React
Xử lý các sự kiện trong DOM và Window bằng React
Debug (gỡ lỗi) React component thông qua React Developer Tools
khái niệm React Context và chia sẻ state qua các component với React Context
Cách quản lý state(trạng thái) bằng Hooks trên React Component
React strict mode (chế độ phát triển) trong React
Quản lý state (trạng thái) trong React Class Component

THÊM BÌNH LUẬN Cancel reply

Dịch vụ thiết kế Wesbite

NỘI DUNG MỚI CẬP NHẬT

2. PHÂN TÍCH VÀ ĐẶC TẢ HỆ THỐNG

1. TỔNG QUAN KIẾN THỨC THỰC HÀNH TRIỂN KHAI DỰ ÁN CÔNG NGHỆ THÔNG TIN

Hướng dẫn tự cài đặt n8n comunity trên CyberPanel, trỏ tên miền

Mẫu prompt tạo mô tả chi tiết bối cảnh

Một số cải tiến trong ASP.NET Core, Razor Page, Model Binding, Gabbage collection

Giới thiệu

hocvietcode.com là website chia sẻ và cập nhật tin tức công nghệ, chia sẻ kiến thức, kỹ năng. Chúng tôi rất cảm ơn và mong muốn nhận được nhiều phản hồi để có thể phục vụ quý bạn đọc tốt hơn !

Liên hệ quảng cáo: [email protected]

Kết nối với HỌC VIẾT CODE

© hocvietcode.com - Tech888 Co .Ltd since 2019

Đăng nhập

Trở thành một phần của cộng đồng của chúng tôi!
Registration complete. Please check your email.
Đăng nhập bằng google
Đăng kýBạn quên mật khẩu?

Create an account

Welcome! Register for an account
The user name or email address is not correct.
Registration confirmation will be emailed to you.
Log in Lost your password?

Reset password

Recover your password
Password reset email has been sent.
The email could not be sent. Possible reason: your host may have disabled the mail function.
A password will be e-mailed to you.
Log in Register
×