Hỏi - đáp Nơi cung cấp thông tin nghề nghiệp và giải đáp những thắc mắc thường gặp của bạn

Tái sử dụng code với HOCs và Render Prop trong ReactJS

1. Higher-order components (HOCs)

Higher-order components (HOCs) là một kỹ thuật tái sử dụng code rất quen thuộc khi lập trình với React. Nói một cách đơn giản, HOC là một hàm nhận vào một component và trả về một component mới. Nếu sử dụng react-redux hay react-router, bạn hẳn đã quen thuộc với HOC connect() và withRouter().

Dưới đây là một HOC đơn giản, giúp gắn tọa độ của con trỏ chuột vào một component.

Một trong những lí do khiến HOCs phổ biến là vì kĩ thuật này sử dụng lớp của ES6 (class) ngay từ đầu. Kể từ React 16, lớp là cơ chế mặc định khi xây dựng component, thay thế hoàn toàn cho React.createClass() ở các phiên bản trước. Điều này hợp lý, vì lớp đã được hầu hết các trình duyệt hiện tại hỗ trợ mặc định.

Tuy nhiên, việc dùng HOCs cũng có những hạn chế:

  • HOCs dễ gây bối rối: Việc sử dụng nhiều HOCs cho một component dễ dẫn đến tình trạng không biết props này là do HOC nào cung cấp.
  • Trùng lặp tên props: Nếu bạn có 2 HOCs sử dụng cùng một tên cho prop, chúng sẽ bị ghi đè lên nhau.

2. Render Prop

"Render prop", "render callback", hay “function as a child” là những tên gọi cho kỹ thuật đưa một hàm để render vào làm prop. Bằng cách này, các components có thể chia sẻ dữ liệu theo một cách rõ ràng và không bị ràng buộc lẫn nhau.

Chúng ta có thể viết ví dụ withMouse() ở trên theo hướng render prop.

hoặc "function as a children".

Như bạn thấy, hàm để render có thể được truyền vào như một prop, hay là children của component.

Ý tưởng chính ở đây là: chúng ta có một component tên Mouse rất rõ ràng, cung cấp giá trị tọa độ (x, y) của con trỏ chuột. Nhờ đó, MyComponent có thể render tùy ý với dữ liệu này.

Hướng tiếp cận nêu trên giúp giải quyết được tình trạng “dễ gây bối rối” và “dễ trùng lặp tên props”, vì dữ liệu được truyền một cách trực tiếp thông qua từng component, và cũng không có cơ chế chia sẻ props hay state giữa các components với nhau, trừ khi chúng ta thật sự muốn điều đó.

Lưu ý:

Bạn có thể chuyển đổi từ render prop thành HOC, nhưng không thể làm được điều ngược lại. Chẳng hạn như:

Hạn chế của việc dùng Render Prop

Cho đến hiện tại, hạn chế duy nhất của hướng tiếp cận này là: việc sử dụng nhiều render props trong một component có thể tạo ra nhiều hàm lồng nhau, làm mã nguồn hơi khó nhìn.

Ví dụ, khi dùng 2 render props tưởng tượng ReactRedux và ReactRouter.

Cho nên, nếu phải thường xuyên dùng hơn 3 render props trong một component, có lẽ bạn nên tạo một component bao đóng (wrapper) cả 3 lại để hạn chế code bị trùng lắp.

Kết luận

Render prop đem đến nhiều lợi thế hơn so với HOC khi giải quyết vấn đề tái sử dụng code trong React. Tuy vậy bạn cũng nên cân nhắc khi sử dụng, vì việc thay thế những HOC quen thuộc như connect() của react-redux hay withRouter() của react-router có thể sẽ gây khó hiểu cho thành viên mới trong team của bạn.

Via ehkoo.com