Chào các bạn, hôm nay chúng ta sẽ đi sâu vào useEffect() trong React Hooks, một công cụ mạnh mẽ cho phép chúng ta xử lý các side effects trong các component. Chúng ta sẽ không chỉ tìm hiểu cú pháp mà còn xem xét các tình huống sử dụng nâng cao và một số mẹo thực hành.
1. Khái Niệm Cơ Bản Về useEffect()
useEffect
cho phép bạn thực hiện các tác vụ ngoài việc render, như gọi API, theo dõi sự kiện, và thao tác với DOM.
- Side effects bao gồm bất kỳ hoạt động nào mà không phải chỉ là render lại component, ví dụ như:
- Gọi một API để lấy dữ liệu.
- Thiết lập một listener cho sự kiện.
- Cập nhật tiêu đề của trang.
2. Cú Pháp useEffect
useEffect(() => {
// Code cho side effect
return () => {
// Clean-up code
};
}, [dependencies]);
- Callback function: Nơi thực hiện side effect.
- Clean-up function: Hàm trả về để dọn dẹp.
- Dependency array: Xác định khi nào
useEffect
sẽ chạy lại.
3. Ví Dụ Cơ Bản: Lấy Dữ Liệu Từ API
import React, { useEffect, useState } from 'react';
const DataFetchingComponent = () => {
const [data, setData] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
const fetchData = async () => {
const response = await fetch('https://api.example.com/data');
const result = await response.json();
setData(result);
setLoading(false);
};
fetchData();
}, []); // Gọi một lần khi component mount
if (loading) return Loading...;
return (
{data.map(item => (
{item.name}
))}
);
};
export default DataFetchingComponent;
4. Ví Dụ Nâng Cao: Theo Dõi Sự Thay Đổi
Giả sử bạn muốn theo dõi một state và thực hiện một tác vụ mỗi khi state đó thay đổi.
import React, { useEffect, useState } from 'react';
const CounterComponent = () => {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `Count: ${count}`; // Cập nhật tiêu đề trang
return () => {
console.log(`Clean up for count: ${count}`); // Clean-up khi count thay đổi
};
}, [count]); // Chạy lại khi count thay đổi
return (
Count: {count}
setCount(count + 1)}>Increase
);
};
export default CounterComponent;
5. Tình Huống Sử Dụng Nâng Cao
a. Thực hiện Subscriptions
Giả sử bạn muốn đăng ký một sự kiện, ví dụ như theo dõi vị trí của chuột:
import React, { useEffect, useState } from 'react';
const MousePosition = () => {
const [position, setPosition] = useState({ x: 0, y: 0 });
useEffect(() => {
const handleMouseMove = (event) => {
setPosition({ x: event.clientX, y: event.clientY });
};
window.addEventListener('mousemove', handleMouseMove);
return () => {
window.removeEventListener('mousemove', handleMouseMove); // Dọn dẹp khi component unmount
};
}, []); // Chạy một lần khi component mount
return (
X: {position.x}, Y: {position.y}
);
};
export default MousePosition;
b. Sử Dụng useEffect Với Các Dependency Phức Tạp
Bạn có thể sử dụng nhiều dependencies để kiểm soát khi nào useEffect
được gọi:
import React, { useEffect, useState } from 'react';
const ComplexEffectComponent = () => {
const [count, setCount] = useState(0);
const [value, setValue] = useState('');
useEffect(() => {
const timer = setTimeout(() => {
console.log(`Count: ${count}, Value: ${value}`);
}, 1000);
return () => clearTimeout(timer); // Dọn dẹp timer
}, [count, value]); // Gọi lại khi count hoặc value thay đổi
return (
setValue(e.target.value)}
/>
setCount(count + 1)}>Increase Count
Count: {count}
);
};
export default ComplexEffectComponent;
6. Các Lưu Ý Quan Trọng
- Tránh Side Effects Trong Render: Đừng thực hiện side effects trong phần render của component, vì điều này có thể dẫn đến các vấn đề về hiệu suất và lỗi không mong muốn.
- Chỉ Sử Dụng Dependency Array Khi Cần Thiết: Nếu bạn bỏ qua dependency array,
useEffect
sẽ chạy lại sau mỗi lần render. Nếu bạn truyền một mảng rỗng, nó sẽ chỉ chạy một lần khi component mount.
- Lưu Ý Đến Clean-up: Luôn nhớ dọn dẹp các tác vụ để tránh rò rỉ bộ nhớ.
7. Bài Tập Thực Hành
Hãy thử tạo một ứng dụng sử dụng useEffect
để tạo một stopwatch. Mỗi giây, nó sẽ tăng một giá trị, và bạn cần sử dụng clean-up function để dừng stopwatch khi component unmount.
Nếu bạn có câu hỏi hoặc cần thêm thông tin, đừng ngần ngại hỏi nhé! Chúc các bạn học tốt!