componentWillUnmount được gọi ngay trước khi component bị xóa khỏi DOM — đây là nơi bắt buộc phải cleanup để tránh memory leak.
Ví dụ: clearInterval(this.timerId), hủy WebSocket subscription, gọi controller.abort() để cancel fetch đang chạy. Không được gọi setState ở đây vì component không còn tồn tại. Tương đương hàm cleanup return () => clearInterval(id) trả về trong useEffect.