Thứ tự lựa chọn:
1. Tính thẳng trong render — mặc định đúng. Không có nguồn sự thật thứ hai để đồng bộ, không thể lệch dữ liệu.
2. Bọc useMemo — chỉ khi phép tính thật sự nặng và đã đo được (lọc/sắp xếp vài nghìn phần tử, xử lý chuỗi lớn), hoặc khi kết quả cần giữ tham chiếu ổn định để làm dependency cho memo/useEffect.
3. Lưu vào state + useEffect đồng bộ — gần như luôn sai. Tạo thêm một lần render, dữ liệu có một khoảng thời gian lệch nhau, và phải nhớ cập nhật ở mọi nhánh.
// wrong: extra state + extra render + can go out of sync
const [visible, setVisible] = useState([])
useEffect(() => { setVisible(items.filter(i => i.active)) }, [items])
// right
const visible = items.filter(i => i.active)
// right when measured as expensive
const visible = useMemo(() => items.filter(i => i.active), [items])Khi state dẫn xuất có vẻ cần thiết, thường là dấu hiệu cấu trúc state sai — lưu id đang chọn thay vì lưu cả object đang chọn, để object luôn được suy ra từ danh sách gốc và không bao giờ cũ.
Nếu chỉ cần reset giá trị dẫn xuất khi một prop đổi, dùng key để React tạo lại component thay vì viết effect đồng bộ.