Sự quan trọng của key props trong ReactJS

Đặ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ủa new 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ủa new 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 reconciliationkey đượ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à numberkey 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 ^^

Related Posts

Leave a Reply

Your email address will not be published. Required fields are marked *