Class 06: useEffect hook
useEffect – Hook theo dõi và side effect
useEffect dùng để làm gì?
useEffect
là một hook của React được sử dụng để xử lý các side effects trong component. Side effects là các tác động phụ bên ngoài ngoài việc render giao diện, ví dụ như:
Gọi API lấy dữ liệu.
Đăng ký sự kiện (event listener).
Cập nhật DOM thủ công.
Khởi tạo hoặc dọn dẹp timer (setInterval, setTimeout).
Theo dõi hoặc ghi log dữ liệu khi state hoặc props thay đổi.
useEffect
cho phép bạn chạy một hàm nào đó sau khi component được render (hoặc khi dependency thay đổi), không làm cản trở quá trình render UI.
Cách dùng useEffect với dependency array
Cú pháp cơ bản:
useEffect(() => {
// Code side effect
return () => {
// Cleanup (nếu cần)
};
}, [dependencies]);
Tham số đầu tiên: hàm callback chạy khi component render và khi dependency thay đổi.
Tham số thứ hai: mảng
dependencies
là các biến React theo dõi. Nếu giá trị trong mảng này thay đổi, hàm callback sẽ chạy lại.Nếu không truyền dependency array, effect sẽ chạy sau mỗi lần render (gây lặp lại nhiều lần).
Nếu truyền mảng rỗng
[]
, effect chỉ chạy 1 lần khi component mount (tương đương componentDidMount).
Các trường hợp dùng useEffect theo dependency
[]
(mảng rỗng): chạy 1 lần sau khi component mount. Ví dụ: gọi API một lần hoặc đăng ký event listener.[someVar]
: chạy mỗi khi biếnsomeVar
thay đổi. Ví dụ: khi user nhập input, muốn theo dõi giá trị input để làm gì đó.Không truyền mảng dependency: chạy sau mỗi lần render (ít dùng vì gây hiệu suất kém).
Cleanup function trong useEffect
Khi effect tạo ra các side effect có thể tồn tại lâu (ví dụ: timer, event listener), ta cần dọn dẹp để tránh rò rỉ bộ nhớ hoặc hành vi không mong muốn.
useEffect
trả về một hàmcleanup
sẽ được gọi trước khi effect chạy lại hoặc khi component unmount (gỡ bỏ).
Ví dụ cleanup:
useEffect(() => {
const intervalId = setInterval(() => {
console.log('Tick');
}, 1000);
return () => {
clearInterval(intervalId); // Dọn dẹp timer khi component unmount hoặc effect chạy lại
};
}, []);
Ví dụ thực hành chi tiết
'use client';
import { useState, useEffect } from 'react';
export default function UseEffectExample() {
const [count, setCount] = useState(0);
const [inputValue, setInputValue] = useState('');
// Effect theo dõi count
useEffect(() => {
console.log(`Count đã thay đổi: ${count}`);
}, [count]); // chỉ chạy khi count thay đổi
// Effect theo dõi inputValue
useEffect(() => {
console.log(`InputValue đã thay đổi: ${inputValue}`);
}, [inputValue]);
// Effect chạy 1 lần khi component mount (tạo interval)
useEffect(() => {
const intervalId = setInterval(() => {
console.log('Interval đang chạy mỗi giây');
}, 1000);
// Cleanup interval khi unmount
return () => {
clearInterval(intervalId);
console.log('Interval đã được dọn dẹp');
};
}, []);
return (
<div style={{ padding: 20 }}>
<h2>useEffect – Ví dụ theo dõi và side effect</h2>
<button onClick={() => setCount(count + 1)}>Click đếm số lần: {count}</button>
<div style={{ marginTop: 20 }}>
<label>
Nhập text:
<input
type="text"
value={inputValue}
onChange={e => setInputValue(e.target.value)}
placeholder="Gõ gì đó..."
/>
</label>
</div>
</div>
);
}
Giải thích ví dụ
Mỗi khi nhấn nút, state
count
thay đổi, effect đầu tiên chạy in ra log.Mỗi khi nhập input, state
inputValue
thay đổi, effect thứ hai chạy.Khi component mount, effect thứ ba tạo timer
setInterval
chạy log mỗi giây.Khi component unmount, hàm cleanup dọn dẹp timer để không còn chạy nữa.
Bài tập thực hành
Tạo component đếm số lần click và hiển thị số lần click.
Theo dõi giá trị input text và in ra console mỗi khi thay đổi.
Tạo
setInterval
đếm ngược từ 10 đến 0, mỗi giây giảm 1. Khi đếm đến 0, dừng timer.Dùng cleanup function để dọn timer khi component unmount.
Thêm nút "Reset" để khởi động lại đếm ngược.
Last updated