Chào bạn đọc. Ngay bây giờ, tôi xin chia sẽ về các chủ đề ít người biết xung quanh cuộc sống bằng nội dung ReactJS: Tìm hiểu Higher Order Components

Thành phần thứ tự cao hơn (HOC) là một kỹ thuật nâng cao trong React nhằm mục đích sử dụng lại logic của các thành phần. Vậy HOC là gì? Làm thế nào để sử dụng HOC?

HOC là gì?

HOC – Thành phần thứ tự cao hơn không phải là một API của React, nhưng được coi là một mẫu của React.

Đừng Bỏ Lỡ

Nhận miễn phí 3.000.000 SHIB. Cơ hội x100 lần tài khoản với SHIB

tim-hieu-cao-order-component-phan-1
Luồng HOC

HOC thường được triển khai dưới dạng một hàm nhận một thành phần và trả về một thành phần mới.

const EnhancedComponent = higherOrderComponent(WrappedComponent);

Nếu một thành phần sử dụng các đạo cụ để xử lý và hiển thị thành giao diện người dùng, thì HOC sẽ nhận một thành phần và chuyển đổi nó thành một thành phần khác.

HOC được sử dụng rộng rãi trong các thư viện React (Redux, Relay, v.v.)

Thuận lợi:

  • Cho phép sử dụng lại mã, logic thành phần.
  • Thêm, thay đổi logic đầu tiên cho một thành phần mới trước khi trả về (hiển thị chiếm quyền điều khiển)
  • Điều khiển nhà nước và đạo cụ.

Hướng dẫn sử dụng HOC

Trong React, các thành phần là chìa khóa để sử dụng lại. Chúng ta có thể tìm thấy một số logic tương tự trong các thành phần, mặc dù chúng sử dụng các hành động và dữ liệu khác nhau.

Ví dụ: thành phần UserList lấy dữ liệu từ trạng thái và hiển thị danh sách người dùng:

const users = [
  
    id: "user1",
    username: "Danny Le",
    job: "Developer",
    age: "27",
    gender: "male",
    level: "gold",
    email: "danny.thanhtruc@gmail.com",
  ,
  
    id: "user2",
    username: "Vivian Le",
    job: "Developer",
    age: "27",
    gender: "male",
    level: "silver",
    email: "vivian.le@gmail.com",
  ,
];

function User(props) 
  const  data  = props;
  return (
    <>
      <hr />
      <p>
        <b>User name:</b> data.username
      </p>
      <p>
        <b>Job:</b> data.job
      </p>
      <p>
        <b>Level:</b> data.level
      </p>
      <p>
        <b>Contact:</b> data.email
      </p>
    </>
  );


class UserList extends React.Component 
  constructor(props) 
    super(props);
    this.state = 
      users: [],
    ;
  

  componentDidMount() 
    this.setState( users );
  

  render() 
    return (
      <>
        <h1>List User</h1>
        this.state.users.map((user) => (
          <User data=user />
        ))
      </>
    );
  

Sau đó, chúng tôi có một thành phần ProductList với một mẫu tương tự:

const products = [
  
    availableSizes: ["S", "XS"],
    currencyFormat: "$",
    currencyId: "USD",
    description: "4 MSL",
    id: 12,
    installments: 9,
    isFreeShipping: true,
    price: 10.9,
    sku: 12064273040195392,
    style: "Black with custom print",
    title: "Cat Tee Black T-Shirt",
  ,
  
    availableSizes: ["M"],
    currencyFormat: "$",
    currencyId: "USD",
    description: "",
    id: 13,
    installments: 5,
    isFreeShipping: true,
    price: 29.45,
    sku: 51498472915966370,
    style: "Front print and paisley print",
    title: "Dark Thug Blue-Navy T-Shirt",
  ,
];

function Product(props) 
  const  data  = props;
  return (
    <>
      <hr />
      <p>
        <b>Title:</b> data.title
      </p>
      <p>
        <b>Style:</b> data.style
      </p>
      <p>
        <b>Price:</b> data.price
      </p>
      <p>
        <b>Description:</b> data.description
      </p>
      <p>
        <b>Free shipping:</b> data.isFreeShipping
      </p>
    </>
  );


class ProductList extends React.Component 
  constructor(props) 
    super(props);
    this.state = 
      products: [],
    ;
  

  componentDidMount() 
    this.setState( products );
  

  render() 
    return (
      <>
        <h1>List Product</h1>
        this.state.products.map((product) => (
          <Product data=product />
        ))
      </>
    );
  

Thành phần UserList và ProductList không giống nhau. Chúng nhận dữ liệu khác nhau để setState và hiển thị nội dung khác nhau. Tuy vậy, Các thành phần UserList và ProductList có logic chung như:

  • Cả hai đều khởi tạo một mảng dữ liệu trống ở trạng thái.
  • Sau khi kết xuất, tất cả đều gọi hàm setState để cập nhật dữ liệu.
  • Hàm render có tiêu đề, đi ngang qua mảng dữ liệu của trạng thái để kết xuất các mục theo dữ liệu tương ứng.

Trong một ứng dụng lớn, có thể có rất nhiều logic như trên được sử dụng lặp đi lặp lại. Chúng tôi cần một nơi để tập hợp các lôgic này để chia sẻ với các thành phần khác. Tại thời điểm này, HOC đang phát huy thế mạnh của mình.

Chúng ta viết thêm một hàm nữa để tạo các thành phần có cùng logic như ví dụ UserList và ProductList ở trên. Hàm này sẽ nhận một thành phần và trả về dữ liệu dưới dạng đạo cụ. Chúng tôi tạo một hàm có tên withSubscription lấy thành phần con, dữ liệu và tiêu đề như sau:

function withSubscription(WrappedComponent, dataSource, title) {
  // ...trả về một component khác
  return class extends React.Component 
    constructor(props) 
      super(props);
      this.state = 
        dataSource: [],
      ;
    

    componentDidMount() 
      this.setState( dataSource );
    

    render() 
      // ... và render component đầu vào với dữ liệu mới!
      return (
        <>
          <h1>title</h1>
          this.state.dataSource.map((data) => (
            <WrappedComponent data=data />
          ))
        </>
      );
    
  ;
}

Sau đó, chúng ta chỉ cần gọi hàm withSubscription ở trên, truyền vào các đối số cần thiết và hiển thị giống như một thành phần bình thường như sau:

const UserList = withSubscription(User, users, "User List");
const ProductList = withSubscription(Product, products, "Product List");

function App() 
  return (
    <div className="App">
      <UserList />
      <ProductList />
    </div>
  );


const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
tim-hieu-cao-order-component-phan-1
Danh sách người dùng hiển thị kết quả trên trình duyệt
tim-hieu-cao-order-component-phan-1
Danh sách sản phẩm hiển thị kết quả trên trình duyệt

HOC không sửa đổi hoặc thay đổi thành phần đầu vào WrappedComponent, mà chỉ kế thừa hành vi của thành phần này.

HOC ‘sáng tác‘thành phần đầu vào bởi’gói‘nó nằm trong một thành phần.

HOC là một thành phần tinh khiết (không có tác dụng phụ).

Thành phần bên trong có thể nhận tất cả các đạo cụ (các đối số của HOC: dữ liệu, tiêu đề …) để sử dụng cho việc kết xuất. HOC không quan tâm thành phần sẽ sử dụng dữ liệu như thế nào, ngược lại thành phần con sẽ không quan tâm nơi nhận các đạo cụ.

HOC chỉ là một hàm thông thường, chúng ta có thể thêm bất kỳ tham số nào, số lượng tùy ý.

Mỗi mối quan hệ giữa HOC và thành phần con cũng dựa trên các đạo cụ (tài liệu) giống như các thành phần bình thường, miễn là dữ liệu của HOC cung cấp đủ để đáp ứng logic của thành phần con.

Các thành phần được tạo ra từ HOC vẫn hiển thị trên Công cụ React Dev. Vì vậy, chúng tôi có thể dễ dàng gỡ lỗi:

tim-hieu-cao-order-component-phan-1
Cây thành phần trong React Dev Tool
tim-hieu-cao-order-component-phan-1
Đạo cụ trong Công cụ React Dev

Như vậy, qua bài viết này, chúng ta đã cùng nhau tìm hiểu về khái niệm HOC và cách sử dụng nó. Trong bài tiếp theo, chúng ta sẽ tìm hiểu về các quy ước và lưu ý khi sử dụng Thành phần thứ tự cao hơn. Cảm ơn bạn đã ghé thăm bài viết này!

Bài viết có thông tin từ link: https://reactjs.org/docs/higher-order-components.html

Xem bài viết sau tại: ReactJS: Các thành phần thứ tự cao hơn – HOC (Phần 2)

CÔNG TY CỔ PHẦN TẬP ĐOÀN TINO

  • Trụ sở chính: L17-11, Tầng 17, Tòa nhà Vincom Center, Số 72 Lê Thánh Tôn, P. Bến Nghé, Q.1, TP.
    Văn phòng đại diện: 42 Trần Phú, P.4, Q.5, TP.HCM
  • Điện thoại: 0364 333 333
    Tổng đài miễn cước: 1800 6734
  • Email: sales@tino.org
  • Trang web: www.tino.org

Tổng hợp bởi VEZ