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
Giới thiệu props trong ReactJS và tùy chỉnh thành phần (component) với props

Giới thiệu props trong ReactJS và tùy chỉnh thành phần (component) với props

  • 23-09-2022
  • Toanngo92
  • 0 Comments

Để bắt đầu bài viết này, chúng ta có thể tạo dự án mới hoặc xóa trắng các demo cũ và áp dụng code mẫu sau trong file App.js

Tạo một 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

Tạo file components/product/ProductComponent.js

const ProductComp = () => {
    return (<div>Product Component</div>)
}

export default ProductComp

Sửa code file App.js như sau:

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

const App = () => {

  return (
    <div className='container'>
        {data.map((item) => {
            return (<ProductComp />)
        })}
    </div>
  )

}

export default App;

Cấu trúc thư mục và output:

Ở đây, chúng ta thấy dữ liệu của ProductComponent vẫn đang tĩnh, mình sẽ bắt đầu truyền props để có thể sử dụng và in ra thuộc tính name bên trong đối tượng sản phẩm của mảng data như ví dụ dưới.

Mục lục

  • Thêm props vào component
  • Tạo Predictable Props với PropTypes và defaultProps

Thêm props vào component

Sửa file App.js thành cấu trúc như sau:

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

const App = () => {

  return (
    <div className='container'>
        {data.map((item) => {
            return (<ProductComp key={item.id} name={item.name} />)
        })}
    </div>
  )

}

export default App;

Lưu ý: chúng ta cần đưa key vào ProductComp khi truyền props, mặc dù dự án vẫn chạy nhưng nếu không có key, compiler sẽ warning:

react-jsx-dev-runtime.development.js:87 
        
       Warning: Each child in a list should have a unique "key" prop.

Check the render method of `App`. See https://reactjs.org/link/warning-keys for more information.
    at ProductComp (http://localhost:3000/static/js/bundle.js:108:20)
    at App

Sửa nội dung file ProductComponent.js

const ProductComp = (props) => {
    const name = props
    console.log(name)
    return (<div>{name.name}</div>)
}

export default ProductComp

Output

Chúng ta thấy rằng giá trị của biến name mình vừa gán bằng props truyền vào khi log ra sẽ là một object, chúng ta truy vấn trực tiếp vào thuộc tính name của biến để có thể in dữ liệu ra JSX.

Nâng cao hơn, chúng ta sẽ chỉnh sửa mã nguồn để có thể in ra bảng dữ liệu tất cả sản phẩm của mảng data.

Cách 1: truyền toàn bộ dữ liệu qua 1 biến

Sửa 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} product={item} />)
          })}
        </tbody>
      </table>
    </div>
  )

}

export default App;

Sửa nội dung file ProductComponent.js

const ProductComp = (props) => {
    const product = props.product
    console.log(product)
    return (<tr>
        <td>{product.id}</td>
        <td>{product.name}</td>
        <td>{product.type}</td>
        <td>{product.ppu}</td>
        </tr>)
}

export default ProductComp

Output

Cách 2: truyền dữ liệu thành các biến khác nhau

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} />)
          })}
        </tbody>
      </table>
    </div>
  )

}

export default App;

Sửa nội dung file ProductComponent.js

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

export default ProductComp

Output vẫn không thay đổi. (Lưu ý, để hứng giá trị trong ProductComp, tham số hứng sẽ là một object, và mỗi thuộc tính từ <ProductComp /> trong App.js truyền vào sẽ tương ứng lần lượt với thuộc tính của object đó.)

Tiếp theo, chúng ta kết hợp sự kiện onClick để hiển thị các thông tin còn lại của dữ liệu mẫu ra như batters, topping ( 2 thuộc tính này giá trị là object mảng và mảng ).

Sửa 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;

Sửa nội dung file ProductComponent.js

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

Output:

Tạo Predictable Props với PropTypes và defaultProps

Sau khi thêm props vào component của mình, bạn sẽ sử dụng PropTypes để xác định loại dữ liệu mà bạn mong đợi một thành phần nhận được. PropTypes là một hệ thống kiểu đơn giản để kiểm tra xem dữ liệu có khớp với kiểu mong đợi trong thời gian chạy hay không.
Chúng đóng vai trò như cả tài liệu hướng dẫn và công cụ kiểm tra lỗi sẽ giúp ứng dụng của bạn có thể dự đoán được khi nó mở rộng quy mô.

Bước 1: nếu phiên bản ReactJS của bạn phiên bản từ 15.5 trở lên chạy lệnh cài package Proptypes bằng lệnh:

npm install --save prop-types

Chúng ta sửa cấu trúc file components/product/ProductComponent.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
}

Như bạn có thể thấy, có rất nhiều PropTypes khác nhau. Đây chỉ là một ví dụ nhỏ, xem tài liệu React chính thức để xem những tài liệu khác mà bạn có thể sử dụng:

Typechecking With PropTypes – React (reactjs.org)

Hãy bắt đầu với prop id. Ở đây, bạn đang chỉ định rằng id phải là một chuỗi. Các Thuộc tính name, type cũng vậy. ppu là một số, có thể bao gồm cả số thực (float) và số nguyên (integer). showBatters,showTopping là một hàm (func). Mặt khác, batters có một chút khác biệt. Trong trường hợp này, bạn đang chỉ định topping sẽ là một array, nhưng bạn cũng cần chỉ định array này sẽ chứa những gì. Trong trường hợp này, array này sẽ chứa một object. Nếu bạn muốn kết hợp các kiểu dữ liệu, bạn có thể sử dụng một hỗ trợ khác có tên là oneOfType, lấy một mảng các PropType hợp lệ. Bạn có thể sử dụng oneOfType ở bất cứ đâu, vì vậy nếu bạn muốn ppu là một số hoặc một chuỗi, bạn có thể thay đổi nó thành sau:

ppu: PropTypes.oneOfType ([PropTypes.number, PropTypes.string])

Với prop batters cũng phức tạp hơn một chút. Trong trường hợp này, bạn đang chỉ định một đối tượng, nhưng nói rõ hơn một chút, bạn đang nói rõ những gì bạn muốn đối tượng chứa. Để làm điều đó, bạn sử dụng PropTypes.shape, lấy một đối tượng với các trường bổ sung sẽ cần PropTypes của riêng chúng. Hãy để ý trước định nghĩa sử dụng shape mình có comment một lệnh phía trên, với cách sử dụng cũ đó, props sẽ không rõ ràng và khó biểu diễn dữ liệu phức tạp một cách chính xác.

Hiện tại, tất cả dữ liệu đều được tạo hình tốt và khớp với các props. Để xem điều gì sẽ xảy ra nếu PropTypes không khớp, hãy mở dữ liệu của bạn ở trường ppu:

ppu: PropTypes.string.isRequired,

Ứng dụng sẽ không lỗi, tuy nhiên console.log sẽ trả ra warning để thông báo cho chúng ta biết dữ liệu đang sử dụng chưa đúng:

react-jsx-dev-runtime.development.js:87 
        
       Warning: Failed prop type: Invalid prop `ppu` of type `number` supplied to `ProductComp`, expected `string`.
    at ProductComp (http://localhost:3000/static/js/bundle.js:165:5)
    at App

Trong tình huống phía trên, chúng ta thấy có thuộc tính isRequired, nghĩa là chúng được yêu cầu bắt buộc. Nếu bạn không đưa dữ liệu bắt buộc vào, mã sẽ vẫn được biên dịch, nhưng bạn sẽ thấy lỗi thời gian chạy trong console.log.

Nếu props không được yêu cầu bắt buộc, bạn có thể thêm giá trị mặc định. Một phương pháp hay là luôn thêm giá trị mặc định để tránh lỗi thời gian chạy nếu không cần phải có giá trị hỗ trợ. Ví dụ: trong thành phần AnimalCard, bạn đang gọi một hàm với dữ liệu bổ sung. Nếu nó không có ở đó, chức năng sẽ thử và sửa đổi một đối tượng không tồn tại và ứng dụng sẽ gặp sự cố.

Để ngăn chặn sự cố này, hãy thêm một defaultProp nếu không có dữ liệu cho các thuộc tính, ví dụ:

ProductComp.defaultProps = {
    ppu: 0
}

Giờ đây, các props của bạn đã được ghi chép đầy đủ và được yêu cầu hoặc có mặc định để đảm bảo mã có thể dự đoán được. Điều này sẽ giúp các nhà phát triển tương lai (bao gồm cả chính bạn) hiểu một component cần prop gì. Nó sẽ giúp bạn dễ dàng trao đổi và sử dụng lại các component của mình hơn bằng cách cung cấp cho bạn thông tin đầy đủ về cách component sẽ sử dụng dữ liệu mà nó đang nhận.

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
×