Đặt vấn đề
Nếu bạn đã tìm hiểu hay đang làm việc với ReactJS
, mình đoán có lẽ bạn đã từng bắt gặp cảnh báo:
khi đang map()
một mảng danh sách nào đó.
Uhmm thì… sửa theo Stackoverflow
là được rồi 😹😹 Có bao giờ bạn tự hỏi vì sao phải làm như vậy không?
Trong bài viết này chúng ta sẽ cùng trả lời cho câu hỏi đó nhé !
Lý do ReactJS cần key
props
Giả sử, chúng ta render
một mảng mà không thêm key
props:
<li>Devnote 1</li>
<li>Devnote 2</li>
Sau đó, Devnote 3
được thêm vào. Lúc này:
<li>Devnote 1</li>
<li>Devnote 2</li>
<li>Devnote 3</li>
ReactJS
bắt đầu so sánh 2 trees
này để tìm ra điểm khác biệt. Để thực hiện điều này, nó sẽ cùng lặp qua lần lượt tất cả các phần tử con của cả 2 mảng; generate ra chỗ cần cập nhật mỗi khi nhận ra được điểm nào đó khác nhau.
Như vậy thì ở ví dụ trên, phần tử đầu tiên và phần tử thứ 2, okie, giống nhau, phần tử thứ 3 là chỗ được thay đổi, cập nhật thôi ! Nom có vẻ ngon lành cành đào nhỉ 😸😸
Bây giờ, chúng ta lại thêm Devnote 0
vào trước mảng đó:
<li>Devnote 0</li>
<li>Devnote 1</li>
<li>Devnote 2</li>
<li>Devnote 3</li>
Một lần nữa, ReactJS
lại lặp, lại so sánh:
- Phần tử đầu của
old tree
(<li>Devnote 1</li>
) với phần tử đầu củanew tree
(<li>Devnote 0</li>
) ⇒ khác nhau ⇒ cập nhập. - Phần tử thứ 2 của
old tree
(<li>Devnote 2</li>
) với phần tử thứ 2 củanew tree
(<li>Devnote 1</li>
) ⇒ khác nhau ⇒ cập nhập. - …
Ồ, có vẻ như có gì đó phát sinh rồi đây !
Cứ vậy thì ReactJS
sẽ cập nhật lại hết tất cả các phần tử con thay vì nhận ra được <li>Devnote 1</li>
, <li>Devnote 2</li>
, <li>Devnote 3</li>
không thay đổi. Điều này sẽ ảnh hưởng tới performance
của ứng dụng.
Lúc này, key
props sinh ra cho đời bớt khổ (J4F).
Theo Trang chủ ReactJS
:
Keys help React identify which items have changed, are added, or are removed. Keys should be given to the elements a stable identity.
Như vậy, khi chúng ta sửa lại:
<li key={ 0 }>Devnote 0</li>
<li key={ 1 }>Devnote 1</li>
<li key={ 2 }>Devnote 2</li>
<li key={ 3 }>Devnote 3</li>
ReactJS
sẽ sử dụng key
này trong quá trình reconciliation
, so sánh tree cũ
và tree mới
thông qua key của từng phần tử, và kết quả là ReactJS
sẽ nhận ra được phần tử mới là <li key={ 0 }>Devnote 0</li>
được thêm vào phía trước, các phần tử còn lại chỉ là dịch xuống vị trí kế tiếp mà thôi.
Sử dụng giá trị của key
là index
?
Có thể khi bạn xem trong các Tutorial
làm mini-project
nhỏ hay một số các demo
, giá trị của key
là index
(trong map()
)
Bạn thấy có ổn không 🤔 ? Spoil
chút là không nha =))
Bởi vì nếu key
là index
thì khi ta thay đổi vị trí của các phần tử trong mảng (xóa, thêm…), index
cũng sẽ thay đổi và lại xảy ra vấn đề như ví dụ Devnotes
ở mục phía trên.
Best practise
Chính ý nghĩa của key
trong quá trình reconciliation
, key
được recommend nên là các unique value
. Kiểu giá trị của key
không phải lúc nào cũng phải là number
, key
có thể là một string
, hay thậm chí là emoji
kìa ^^
Và để thuận tiện và không cần phải suy nghĩ nhiều, chúng ta có thể set id của mỗi phần tử là giá trị của key
.
Mình cảm ơn các bạn vì đã đọc bài viết này và hy vọng rằng nó có thể giúp ích được cho các bạn ^^