Giới thiệu về useEffect và useLayoutEffect trong React 🌟
Kể từ khi React 16.8 ra đời với sự xuất hiện của Hooks, cách viết component trong React đã có sự thay đổi nổi bật. Trong số các hooks mới, hai hooks chủ chốt là useEffect
và useLayoutEffect
đóng vai trò quan trọng trong việc quản lý side effects. Mặc dù chúng có nhiều điểm tương đồng, nhưng thực tế giữa chúng lại có nhiều khác biệt đáng kể.
Trong bài viết này, mình sẽ trình bày chi tiết về useEffect
và useLayoutEffect
, đồng thời chia sẻ những kinh nghiệm thực tế để bạn có thể chọn lựa sử dụng một cách hợp lý trong các dự án React của mình.
useEffect là gì? 🔍
useEffect
là một hook trong React cho phép bạn thực hiện các tác vụ phụ thuộc (side effects) trong các functional component. Các side effects có thể bao gồm việc gọi API, thao tác với DOM, đăng ký sự kiện, và nhiều hơn nữa.
Lưu ý rằng trong 99% trường hợp, useEffect
là hook mà bạn nên sử dụng.
Cách sử dụng useEffect:
javascript
useEffect(() => {
// Code xử lý side effect ở đây
}, [dependencies]);
Tham số thứ hai là [dependencies]
, một mảng chứa các dependencies cho effect. React sẽ chỉ chạy lại effect khi một trong các dependency này thay đổi. Nếu bạn truyền vào một mảng rỗng []
, effect sẽ chỉ chạy một lần sau render đầu tiên, tương tự như phương thức componentDidMount
trong các class component.
useLayoutEffect là gì? 🤔
useLayoutEffect
thực chất cũng tương tự như useEffect
, nhưng có điểm khác biệt rõ rệt về thời điểm thực thi. Hook này được sử dụng cho các tác vụ cần phải đồng bộ hóa với DOM, như điều chỉnh layout trước khi trình duyệt vẽ lại giao diện người dùng.
Khi nào nên dùng useLayoutEffect:
Bạn nên sử dụng useLayoutEffect
khi cần thực hiện các thay đổi ngay lập tức trên DOM trước khi trình duyệt cập nhật giao diện, nhằm tránh hiện tượng nhấp nháy hoặc giật lag trong quá trình render.
javascript
useLayoutEffect(() => {
// Code tương tác với DOM ở đây
}, [dependencies]);
Cũng giống như useEffect
, useLayoutEffect
nhận một mảng dependencies làm tham số thứ hai.
So sánh useEffect và useLayoutEffect trong thực tế ⚖️
Để làm rõ sự khác biệt của hai hooks này, hãy cùng xem một ví dụ cụ thể:
javascript
import React, { useState, useEffect, useLayoutEffect } from 'react';
const ExampleComponent = () => {
const [count, setCount] = useState(0);
useEffect(() => {
console.log('useEffect chạy sau khi render và paint');
// Giả lập một tác vụ nặng
let i = 0;
while (i < 1000000000) i++;
setCount(prevCount => prevCount + 1);
}, []);
useLayoutEffect(() => {
console.log('useLayoutEffect chạy trước khi paint');
// Thực hiện các thay đổi DOM ở đây
document.getElementById('output').style.color = 'red';
}, [count]);
return (
<div>
<h1 id="output">Số lần render: {count}</h1>
<button onClick={() => setCount(prevCount => prevCount + 1)}>Tăng</button>
</div>
);
};
export default ExampleComponent;
Trong ví dụ này:
useEffect
sẽ chạy sau khi component đã được render và được hiển thị trên màn hình. Nó thực hiện một tác vụ nặng (giả lập) và sau đó cập nhật state, điều này gây ra việc re-render.- Ngược lại,
useLayoutEffect
chạy ngay sau khi tất cả các thay đổi DOM hoàn tất nhưng trước khi trình duyệt thực hiện việc paint. Nó thay đổi màu của phần tử văn bản.
Khi bạn chạy component này, bạn sẽ nhận thấy:
- Màu chữ đỏ xuất hiện ngay lập tức, không có hiện tượng nhấp nháy.
- Giá trị của count tăng lên sau một khoảng thời gian ngắn (do tác vụ nặng trong
useEffect
).
Những lưu ý khi sử dụng useEffect và useLayoutEffect 📝
- Nên ưu tiên sử dụng
useEffect
cho hầu hết các trường hợp, đặc biệt là các tác vụ không yêu cầu đồng bộ với DOM. - Chỉ nên sử dụng
useLayoutEffect
khi cần thao tác với DOM và muốn các thay đổi được áp dụng ngay trước khi trình duyệt paint, nhằm tránh các hiệu ứng nhấp nháy. useLayoutEffect
chạy đồng bộ, nên có thể ảnh hưởng đến hiệu suất của ứng dụng nếu sử dụng không đúng cách. Cần cân nhắc kỹ trước khi quyết định.- Trong môi trường server-side rendering, việc sử dụng
useLayoutEffect
có thể gây ra cảnh báo. Trong trường hợp này, bạn nên dùnguseEffect
hoặc chuyển logic vàouseEffect
với một cờ để chỉ chạy ở client-side.
Kết luận 🎯
Hiểu rõ sự khác biệt giữa useEffect
và useLayoutEffect
sẽ giúp bạn tối ưu hóa hiệu suất của ứng dụng và nâng cao trải nghiệm người dùng. Hãy nhớ rằng trong hầu hết mọi tình huống, useEffect
là lựa chọn an toàn và hiệu quả hơn. Chỉ nên sử dụng useLayoutEffect
khi bạn thực sự cần thiết để đồng bộ hóa với DOM nhằm ngăn chặn các vấn đề về hiển thị.
Hy vọng rằng bài viết này sẽ giúp bạn nắm rõ hai hooks quan trọng trong React. Hãy áp dụng những kiến thức này vào dự án của bạn và đừng ngần ngại thử nghiệm để tìm ra cách sử dụng tối ưu nhất! Nếu bạn có bất kỳ thắc mắc nào hoặc muốn chia sẻ kinh nghiệm của bản thân, hãy để lại comment bên dưới. Chúc các bạn thành công! 💻🚀
source: viblo