← Về danh sách bài họcBài 9/25

🧠 Bài 9: useMemo - Tối Ưu Tính Toán

⏱️ Thời gian đọc: 12 phút | 📚 Độ khó: Trung bình

🎯 Sau bài học này, bạn sẽ:

1. useMemo Là Gì?

useMemo ghi nhớ (memoize) kết quả tính toán, chỉ tính lại khi dependencies thay đổi. Giúp tránh tính toán nặng lặp đi lặp lại mỗi render.

import { useMemo, useState } from 'react';

function ExpensiveList({ items, filter }) {
    // ❌ Không có useMemo: filter chạy LẠI mỗi render
    // const filtered = items.filter(item => item.name.includes(filter));

    // ✅ useMemo: chỉ tính lại khi items hoặc filter thay đổi
    const filtered = useMemo(() => {
        console.log('Đang filter...');
        return items.filter(item => item.name.includes(filter));
    }, [items, filter]);

    return (
        <ul>
            {filtered.map(item => (
                <li key={item.id}>{item.name}</li>
            ))}
        </ul>
    );
}

2. Khi Nào Dùng useMemo?

✅ NÊN dùng khi:
• Tính toán nặng (filter/sort array lớn, đệ quy, tính toán phức tạp)
• Tạo object/array truyền vào dependency của hook khác
• Tránh re-render child component nhận object/array props
❌ KHÔNG nên dùng khi:
• Tính toán đơn giản (cộng, trừ, string concat)
• Giá trị primitive (number, string) — so sánh rẻ
• Premature optimization — đo trước, tối ưu sau!
// ❌ Không cần useMemo: quá đơn giản
const fullName = useMemo(() => first + ' ' + last, [first, last]);

// ✅ Cần useMemo: tính toán nặng
const sortedData = useMemo(() => {
    return [...data].sort((a, b) => {
        // Complex sorting with multiple keys
        return a.score - b.score || a.name.localeCompare(b.name);
    });
}, [data]);

// ✅ Cần useMemo: object truyền vào useEffect dependency
const options = useMemo(() => ({
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(formData)
}), [formData]);

📝 Tóm Tắt