- vừa được xem lúc

Giải ngố về High Order Component trong ReactJS - (Phần 2 - HOC)

0 0 37

Người đăng: Tran Duc Trung

Theo Viblo Asia

Mở đầu

Trong bài viết trước mình đã giới thiệu với tất cả mọi người về Currying function và để tiếp tục series bài viết tìm hiểu về High Order Component thì ngày hôm nay mình sẽ cùng mọi người tìm hiểu nốt về High Order Component, để xem nó là gì và có liên quan gì đến Currying function nhé.

High Order Component

Như trong cuối bài viết trước thì mình đã có nói rằng HOC hoạt động dựa trên nguyên lý của Currying function, tức là 1 function sẽ return ra 1 function mới, vậy thì cũng tương tự như vậy, trong React HOC cũng là 1 function và nó sẽ return ra 1 Component

1 HOC cơ bản sẽ trông như thế này:

const EnhancedComponent = () => WrappedComponent => { return <WrappedComponent />;
}; export default EnhancedComponent ;

Nhìn qua thì có vẻ trông rất giống với Currying function phải không nào, nhưng khác biệt ở chỗ là HOC nó nhận vào 1 Component và return ra Component. Nghe hơi confused 1 tí, vậy thì để cho dễ hiểu thì chúng ta sẽ cùng nhau đi vào ví dụ sau:

Bài toán

Giả sử ta có 2 màn hình khác nhau cùng click vào button để show ra alert của trình duyệt. Nếu như bình thường thì trong mỗi component ta sẽ implement sự kiện hiển thị alert khi user click vào button, và đoạn code này trong 2 component này sẽ trông như thế này

// Component A:
export default function AComponent() { const showAlert = () => { window.alert('User clicked!'); }; return ( <button onClick={showAlert}>Click me!<button> );
}; // Component B:
export default function BComponent() { const showAlert = () => { window.alert('User clicked!'); }; return ( <button onClick={showAlert}>Click me!<button> );
};

Như mọi người có thể thấy là 2 Component trên đang bị lặp logic hiển thị alert và nếu có nhiều Component cũng muốn hiển thị alert thì sao, lúc đấy rõ ràng là chúng ta đang vi phạm phải nguyên tắc DRY (Don't Repeat Yourself).

Để giải quyết được vấn đề này ta có thể áp dụng HOC vào bài toán, tức là ta sẽ viết hàm xử lý logic hiển thị alert ra trong HOC như sau:

const EnhancedComponent = () => WrappedComponent => { // Viết hàm xử lý hiển thị alert trong HOC const showAlert = () => { window.alert('create HOC successfully!'); }; // Return ra 1 Component và truyền hàm xử lý hiển thị alert vào trong Component đó như là 1 prop return () => <WrappedComponent showAlert={showAlert} />;
}; export default EnhancedComponent;

Rồi, như vậy là ta đã vừa định nghĩa xong 1 HOC dùng để xử lý việc hiển thị alert và ta chỉ việc sử dụng HOC giống như làm việc với Currying function thôi:

// Component A:
function AComponent(props) { return ( <button onClick={props.showAlert}>Click me!<button> );
}; export default EnhancedComponent()(AComponent); // Component B:
function BComponent(props) { return ( <button onClick={props.showAlert}>Click me!<button> );
}; export default EnhancedComponent()(BComponent);

Đã xong, đoạn code bị lặp ở 2 component trên đã không còn nữa và nhìn trông chúng có vẻ gọn hơn trước khá là nhiều đấy ?

Nhưng mà khoan đã có phải ở Component nào cũng hiển thị alert với cùng 1 nội dung đâu, vậy để thay đổi nội dung alert chúng ta có thể truyền vào HOC nội dung như là param đầu tiên:

// Truyền nội dung muốn hiển thị trên alert vào param đầu tiên
const EnhancedComponent = content => WrappedComponent => { const showAlert = () => { // Hiển thị content window.alert(content); }; return (props) => <WrappedComponent {...props} showAlert={showAlert} />;
}; export default EnhancedComponent;

Sau đó ta chỉ việc update lại nội dung muốn hiển thị trong 2 component A và B:

// Component A:
...
export default EnhancedComponent('Component A was displayed')(AComponent); // Component B:
...
export default EnhancedComponent('Component B was displayed')(BComponent);

Đến đây thì chắc có lẽ mọi người đã phần nào hiểu được cách hoạt động của HOC rồi nhỉ. Ở trên là ví dụ cơ bản nhất về cách sử dụng HOC với vai trò là 1 WrappedComponent, ngoài ra thì HOC còn có thể sử dụng để truyền các props không liên quan đến các thẻ được bao bọc. Ví dụ:

...
const showAlert = () => { window.alert(content);
}; return (props) => <WrappedComponent {...props} showAlert={showAlert} />;
...

Ngoài ra còn có 1 số pattern nâng cao khác về HOC, tuy nhiên trong khuôn khổ bài viết thì mình không sẽ không đề cập đến chúng, mọi người có thể tìm hiểu thêm sau khi đã nắm được những kiến thức cơ bản về HOC và sử dụng chúng 1 cách thuần thục trong các dự án.

Lưu ý

Khi sử dụng HOC thì có 3 điểm bạn cần lưu ý khi sử dụng là:

  • Không sử dụng HOC trong phương thức render()
  • Các phương thức static cần phải được copy lại
  • Refs không được truyền qua HOC

Kết luận

Trong quá trình làm việc với React thì mọi người có thể bắt gặp HOC ở rất nhiều chỗ như là withRouter của React Router hay hàm connect của React-redux. Mỗi hàm thì đều có 1 đặc điểm riêng, ví dụ như withRouter chỉ nhận vào 1 đối số duy nhất là Component. Để có thể hiểu thêm về HOC thì mọi người có thể tìm hiểu thông qua core của hàm withRouterconnect

Cuối cùng thì mình xin chúc mọi người tự tạo và áp dụng thành công HOC vào dự án của riêng mình nhé!

Bình luận

Bài viết tương tự

- vừa được xem lúc

Cùng tìm hiểu về các hook trong React hooks

Đối với ai đã từng làm việc với React thì chắc hẳn đã có những lúc cảm thấy bối rối không biết nên dùng stateless (functional) component hay là stateful component. Nếu có dùng stateful component thì cũng sẽ phải loay hoay với đống LifeCycle 1 cách khổ sở Rất may là những nhà phát triển React đã kịp

0 0 81

- vừa được xem lúc

Khi nào nên (và không nên) sử dụng Redux

. Công việc quản lý state với những hệ thống lớn và phức tạp là một điều khá khó khăn cho đến khi Redux xuất hiện. Lấy cảm hứng từ design pattern Flux, Redux được thiết kế để quản lý state trong các project JavaScript.

0 0 106

- vừa được xem lúc

ReactJS: Props và State

Nếu bạn đã học ReactJS hay React Native, bạn sẽ thấy các Props và State được sử dụng rất nhiều. Vậy chính xác chúng là gì? Làm thế nào để chúng ta sử dụng chúng đúng mục đích đây.

0 0 41

- vừa được xem lúc

State và Props trong Reactjs

Hello các bạn, tiếp tục seri tìm hiểu về ReactJs hôm nay mình xin giới thiệu đến các bạn hai thứ mình cho là thú vị nhất của ReactJs là State và Props. State bạn có thể hiểu đơn giản là một nơi mà bạn lưu trữ dữ liệu của Component, từ đó bạn có thể luân chuyển dữ liệu đến các thành phần trong Compon

0 0 36

- vừa được xem lúc

Memoization trong React

. 1.Introduction. Memoization có liên quan mật thiết đến bộ nhớ đệm, và dưới đây là một ví dụ đơn giản:. const cache = {}.

0 0 38

- vừa được xem lúc

Nâng cao hiệu suất React Hooks với React.memo, Memoization và Callback Functions

1.Ngăn Re-render và React.memo. React.

0 0 67