Họ đang đo gì
Bạn có hiểu quá trình đối chiếu (reconciliation) không, hay chỉ thêm key để hết cảnh báo.
Trả lời ngắn~30 giây
React so sánh cây cũ và cây mới theo vị trí; key cho nó một định danh ổn định để nhận ra phần tử đã DI CHUYỂN thay vì bị thay nội dung. Dùng index thì key gắn với vị trí chứ không gắn với dữ liệu: chèn một phần tử vào đầu danh sách khiến mọi key dịch đi một bậc, nên React tưởng mọi item đã đổi nội dung — state nội bộ, giá trị input và focus đều đi nhầm hàng.
Giải thích sâu
Điều đáng nói là bug này KHÔNG xuất hiện với danh sách chỉ hiển thị. Nó chỉ lộ ra khi mỗi hàng có state riêng — một ô checkbox, một input đang gõ dở, một hàng đang mở rộng. Vì thế nhiều người dùng index nhiều năm mà không gặp vấn đề, rồi thêm một checkbox vào và có một bug mà không ai nghĩ là do key.
Mặt còn lại cũng hữu ích: đổi key là cách CỐ Ý để reset state của một component. Đặt key={userId} cho một form thì khi userId đổi, React tháo component cũ và dựng cái mới với state ban đầu — sạch hơn nhiều so với một useEffect đi xoá từng trường. Đây là kỹ thuật được react.dev khuyến nghị thẳng.
// Hỏng khi chèn/xoá/sắp xếp lại
{todos.map((todo, i) => <Row key={i} todo={todo} />)}
// Đúng: key gắn với dữ liệu, không gắn với vị trí
{todos.map((todo) => <Row key={todo.id} todo={todo} />)}
// Dùng key để reset state một cách có chủ đích
<ProfileForm key={userId} userId={userId} />Câu hỏi tiếp theo họ sẽ hỏi
?Index có bao giờ dùng được không?
Được, khi cả ba điều kiện đúng: danh sách không bao giờ đổi thứ tự, không chèn/xoá ở giữa, và các item không có state riêng. Ví dụ một danh sách tĩnh render một lần. Ngoài ra thì không.
Trả lời thế này là mất điểm
- Dùng
Math.random()làm key. Mọi render sinh key mới nên React tháo và dựng lại toàn bộ danh sách mỗi lần.