Life Cycle là một phần rất quan trọng trong component. Tuy nhiên, một functional component lại không thể làm việc với các Life Cycle một cách thông thường và useEffect Hooks được sinh ra để thực hiện việc này. Vây, useEffect là gì? Tại sao chúng ta lại nên sử dụng useEffect? Bài viết này sẽ giải đáp những thắc mắc trên giúp bạn!
Tìm hiểu về useEffect trong React
Nếu bạn thực sự cần làm việc với useEffect, bài viết này sẽ có thể hỗ trợ bạn một phần trong việc tìm hiểu. Tuy nhiên, nếu bạn chưa từng tiếp xúc với useEffect hay React bao giờ, bạn sẽ “mất sức” khá nhiều để hiểu hết những gì mà Tino Group chia sẻ dưới đây!
Để làm quen được với useEffect và Hooks nói chung, bạn sẽ cần phải tốn rất nhiều thời gian và công sức để tìm hiểu. Bài viết chỉ giải đáp một phần và không thể bao quát hết nội dung của useEffect nói riêng hay Hooks nói chung.
Hooks là gì?
Hooks là một tính năng mới được công bố và thêm vào từ phiên bản React 16.8. Với Hooks, bạn có thể sử dụng state và rất nhiều tính năng khác của React mà không cần phải thực hiện việc viết class như truyền thống.
Và useEffect chính là một Hook trong những Hooks được công bố.
Một vài công bố của nhà phát triển React về Hooks và tương lai:
- Nếu bạn vẫn thích sử dụng class, bạn vẫn có thể tiếp tục sử dụng.
- Hooks không làm thay đổi bất cứ điều gì trong ứng dụng của bạn
- Hooks tương thích 100% với các phiên bản ứng dụng cũ
Bạn có thể tìm hiểu thêm về Hooks trong tài liệu chính thức của React.
useEffect là gì?
Trước đây, nếu sử dụng class component trong viết code React thì giờ đây, bạn có thể sử dụng useEffect để quản lý vòng đời component trong functional component thay thế cho Life Cycle:
- componentDidMount
- componentDidUpdate
- componentWillUnmount
useEffect sẽ giúp bạn xử lý các logic trong vòng đời của component và được gọi khi component có sự thay đổi. Ngoài ra, chúng ta sẽ có useState sẽ sử dụng state trong functional components.
Triển khai useEffect trong React
Tìm nạp dữ liệu, thiết lập đăng ký hay thay đổi các thành phần DOM trong React đều là những ví dụ về “tác dụng” hay side effect hoặc ngắn gọn hơn là effect.
Có 2 loại side effect chính là:
- Effects không cần Cleanup
- Effects cần phải Cleanup
Để hiểu hơn về useEffect cũng như 2 side effect của useEffect, chúng ta sẽ tìm hiểu rõ hơn ở phần triển khai thử nghiệm useEffect trong React nhé!
useEffect không cần Cleanup
Đôi khi, chúng ta muốn chạy một số mã bổ sung sau khi React đã cập nhật DOM. Network request – mạng yêu cầu, manual DOM mutations – đột biến DOM theo cách thủ công và yêu cầu đăng nhập sẽ là các ví dụ điển hình cho useEffect không cần Cleanup.
Code ví dụ useEffect không cần Cleanup
import React, { useState, useEffect } from 'react';
function Example() {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `Bạn bấm vào tôi ${count} lần`;
});
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
Phân tích ví dụ
Như bạn có thể thấy, khi sử dụng Hook, đồng nghĩa bạn nói với React rằng component của bạn cần phải làm gì sau khi render. React sẽ ghi nhớ điều đó và ghi nhớ chức năng bạn đã truyền đi và gọi chúng lại lần nữa sau khi cập nhật DOM.
Bằng cách này, bạn có thể đặt lại tiêu đề của tài liệu chuyển đổi theo số lần nhấp của bạn. Ngoài ra, bạn còn có thể thực hiện việc tìm nạp dữ liệu hay gọi một số APU bắt buộc khác.
Chắc bạn đang đặt ra một câu hỏi là:
Tại sao lại gọi useEffect bên trong một component?
Đặt useEffect bên trong một component sẽ giúp ta có thể tương tác với biến đếm hoặc bất kỳ một prop nào ngay từ effect. Bạn cũng sẽ không cần một API đặc biệt để đọc trường hợp này vì chức năng này đã có sẵn.
Hook sẽ “nắm lấy” JavaScript và “tránh” các API dành riêng cho React mà JavaScript có sẵn các giải pháp xử lý.
Một câu hỏi tiếp theo sẽ được đặt ra là: Liệu useEffect có tiếp tục chạy sau mỗi lần render hay không?
Có! useEffect vẫn sẽ tiếp tục chạy sau mỗi lần render theo mặc định và ngay cả sau lần hiển thị đầu tiên lẫn mỗi lần cập nhật. Tuy nhiên, bạn vẫn có thể tùy chỉnh được thiết lập mặc định này.
Khi quen làm việc với class, bạn sẽ nghĩ chúng đang “mounting” hay “updating”, bạn có thể nghĩ đơn giản là chúng xuất hiện effects sau mỗi lần render. React sẽ đảm bảo rằng DOM đã cập nhật ngay thời điểm các effect diễn ra.
useEffect cần phải Cleanup
Trong trường hợp bạn muốn thiết lập số lượng đăng ký từ một nguồn bên ngoài. Lúc này, bạn sẽ cần phải dọn dẹp – cleanup để tránh việc rò rỉ bộ nhớ ra ngoài!
Code ví dụ bằng class
Trong class React, để thiết lập đăng ký, bạn sẽ sử dụng componentDidMount và dọn dẹp bằng componentWillUnmount.
Ví dụ: bạn muốn hiển thị trạng thái online của bạn bè, chúng ta sẽ có module ChatAPI làm việc này và code bằng class sẽ như sau:
class TrangThaiBanBe extends React.Component {
constructor(props) {
super(props);
this.state = { isOnline: null };
this.handleThayDoiTrangThai = this.handleThayDoiTrangThai.bind(this);
}
componentDidMount() {
ChatAPI.subscribeToTrangThaiBanBe(
this.props.friend.id,
this.handleThayDoiTrangThai
);
}
componentWillUnmount() {
ChatAPI.unsubscribeFromTrangThaiBanBe(
this.props.friend.id,
this.handleThayDoiTrangThai
);
}
handleThayDoiTrangThai(status) {
this.setState({
isOnline: status.isOnline
});
}
render() {
if (this.state.isOnline === null) {
return ’Đang chạy á...';
}
return this.state.isOnline ? 'Online' : 'Offline';
}
}
Trong ví dụ này, chúng ta có thể thấy componentDidMount và componentWillUnmount sẽ cần phải phản chiếu lại với nhau. Đồng nghĩa với việc bạn sẽ cần phải tách logic ra làm 2 nhưng về một mặt khác, cả 2 đều chỉ liên quan đến 1 effect.
Code ví dụ bằng Hooks
import React, { useState, useEffect } from 'react';
function TrangThaiBanBe(props) {
const [isOnline, setIsOnline] = useState(null);
useEffect(() => {
function handleThayDoiTrangThai(status) {
setIsOnline(status.isOnline);
}
ChatAPI.subscribeToTrangThaiBanBe(props.friend.id, handleThayDoiTrangThai);
// Specify how to clean up after this effect:
return function cleanup() {
ChatAPI.unsubscribeFromTrangThaiBanBe(props.friend.id, handleThayDoiTrangThai);
};
});
if (isOnline === null) {
return 'Đang chạy á...';
}
return isOnline ? 'Online' : 'Offline';
}
Phân tích ví dụ
Như các bạn có thể thấy, với useEffect Tino Group không cần phải tách ra 2 phần riêng biệt để thực hiện cleanup effect. React sẽ tự động chạy đến khi nào dọn dẹp mới thôi.
Có lẽ, bạn sẽ đặt ra câu hỏi: Tại sao chúng ta lại nhận được một function từ effect?
Câu trả lời do đây là một cơ chế tùy chọn dọn dẹp effect. Mỗi effect sẽ có thể trả về một function cleanup effect đó.
Đến đây, chúng ta đã trải qua một “hành trình” tuy không ngắn cũng không dài, nhưng có thể giúp bạn hiểu được useEffect là gì, cũng như cách triển khai useEffect trong thực tế ra sao. Tino Group hi vọng rằng những kiến thức này có thể hỗ trợ bạn trong sự nghiệp lập trình với React.
Bài viết có tham khảo nội dung từ: React Docs, React FAQs, TopDev, FreeTuts, W3Schools,…
Những câu hỏi thường gặp về useEffect
Class có bị gỡ bỏ khỏi React hay không?
Không! Theo chính nhà phát triển React, dù có phát triển nhiều tính năng mới như Hooks nhưng họ không hề có bất cứ kế hoạch nào nhằm gỡ bỏ các class ra khỏi sản phẩm của họ. Nhưng nhà phát triển React khuyến khích bạn nên sử dụng thử Hooks.
Tìm hiểu thêm về useEffect ở đâu?
Nếu bạn cảm giác bài viết thật sự khó hiểu, chúc mừng bạn, bạn sẽ tiếp tục đến với bộ tài liệu đầy đủ (có thể sẽ khó hiểu hơn) về useEffect trong React tại React DOCS. Tại đây, bạn sẽ được đội ngũ phát triển của React hướng dẫn tường tận về cách sử dụng useEffect. Tuy nhiên, nếu bạn không có kiến thức chuyên môn vững và lượng từ vựng tiếng Anh chuyên ngành tốt, bạn sẽ rất khó để tiếp thu những kiến thức này.
Phiên bản React nào có thể sử dụng Hooks?
Để sử dụng Hooks, tất cả các gói React bạn sử dụng sẽ cần phải từ phiên bản 16.8.0 trở lên. Nếu bạn không update, Hooks sẽ không thể sử dụng được.
Nên sử dụng Hooks, class hay sử dụng cả 2?
Khi đã sẵn sàng với sự thay đổi, bạn có thể thử làm quen và viết bằng Hooks trong các component của mình. Bạn cũng nên nhắc nhở “người cùng hội cùng thuyền” không nên viết lại các class đã có sẵn trong Hooks, cũng như bạn nên khuyến khích họ sử dụng Hooks vì Hooks cũng khá dễ để làm quen.