Nội dung bài viết
Ở bài viết trước chúng ta đã tìm hiểu về Rendering Cycle trong ReactJS để có thể hiểu được 2 phase chính trong ReactJS là render và commit. Thì trong phase render, có một bước khá quan trọng chính là so sánh UI cũ và UI mới để quyết định nên giữ lại, cập nhật, mount hay unmount được gọi là Reconciliation.
Ví dụ:

Nhìn bằng mắt thường, ta thấy có vẻ như đây là 2 input khác nhau:
- Một input cho công ty.
- Một input cho cá nhân.
Nhưng với React, cả hai đều có cùng một type là Input.
Vì vậy khi isDisplay thay đổi, React không nghĩ rằng cần xoá input cũ rồi tạo input mới. React chỉ nghĩ:
À, vẫn là component
Input, chỉ khác props thôi.
Kết quả là React tái sử dụng lại component cũ, chỉ cập nhật props mới như id, placeholder.
Điều này dẫn đến một hành vi khá bất ngờ:
Nếu bạn gõ gì đó vào input, sau đó toggle qua lại, nội dung có thể vẫn còn, vì component chưa bị unmount.
Tại sao lại như vậy ? Để hiểu được tại sao thì mình sẽ mổ xẻ cho các bạn xem cách React nó nhìn UI như thế nào nhé.
Khi các bạn viết

Thì trong React thực ra nó đại khái chuyển JSX thành một cấu trúc object như thế này:

Nếu là DOM element thật như:

React sẽ hiểu object là:

Điểm quan trọng nằm ở type.
Khi render lại, React sẽ so sánh UI cũ và UI mới dựa trên những thông tin như type key props position
Trong đó, type là yếu tố cực kỳ quan trọng mà các bạn cần phải chú ý. Trong trường hợp
type giống nhau
React sẽ tái sử dụng lại component đó
Ví dụ:

Trước khi state thay đổi:

Sau khi state thay đổi:

React thấy:
type cũ: Input
type mới: InputVì type giống nhau, React sẽ giữ lại component cũ và chỉ update props.
Nói cách khác:
Cùng
type→ React có xu hướng reuse.
Kháctype→ React sẽ unmount cái cũ và mount cái mới.
Nếu type khác nhau
Ví dụ:

Lúc này UI cũ và UI mới có dạng:
// trước
{
type: Input
}
// sau
{
type: TextPlaceholder
}React thấy type đã thay đổi từ Input sang TextPlaceholder.
Kết quả:
Inputbị unmount.- State bên trong
Inputbị mất. TextPlaceholderđược mount mới.
Đây là lý do khi đổi qua một component khác hoàn toàn, state cũ sẽ không còn.
Reconciliation với array children
Trong React, children thường được xem như một array.
Ví dụ:

React có thể hiểu gần giống như:

Khi render lại, React sẽ so sánh từng item theo vị trí:
vị trí 0: Checkbox cũ vs Checkbox mới
vị trí 1: Input cũ vs Input mớiNếu ở cùng một vị trí, cùng một type, React sẽ reuse.
Đây là lý do ví dụ ban đầu bị reuse input:

Dù props khác nhau, nhưng Input luôn nằm ở cùng một vị trí trong children array.
Cách ép React tạo input mới
Nếu bạn muốn React hiểu rằng đây là 2 input khác nhau thật sự, bạn có thể dùng key.

Bây giờ React sẽ thấy:
// trước
{
type: Input,
key: "company-email"
}
// sau
{
type: Input,
key: "person-email"
}Dù type vẫn là Input, nhưng key khác nhau.
Kết quả:
React sẽ không reuse component cũ nữa.
Nó sẽ unmount input cũ và mount input mới.
Vì vậy state bên trong input sẽ được reset.
Key không chỉ dùng cho list
Nhiều người nghĩ key chỉ dùng khi render list:

Nhưng bản chất của key là:
Giúp React nhận diện một element giữa các lần render.
Trong list, key rất quan trọng vì item có thể bị thêm, xoá, đổi vị trí. Nếu không có key, React sẽ dễ reuse sai component.
Ví dụ:
[
{ type: Input },
{ type: Input }
]Nếu đảo vị trí 2 input, React không biết input nào là input nào. Nó chỉ thấy cả hai đều là Input.
Khi có key:
[
{ type: Input, key: "1" },
{ type: Input, key: "2" }
]React có thể hiểu:
Input có key
"1"vẫn là input đó, dù nó có đổi vị trí.
Khi nào cần dùng key
Bạn nên dùng key khi:
1. Render list

Không nên dùng index làm key nếu list có thể thêm, xoá, sắp xếp lại.

2. Muốn reset state của component
Ví dụ đổi form theo user:

Khi userId đổi, React sẽ remount ContactForm, từ đó reset state bên trong form.
3. Muốn React phân biệt 2 component cùng type

Cả hai đều là AuthForm, nhưng về mặt nghiệp vụ, login form và register form là 2 trạng thái khác nhau. Dùng key giúp React hiểu điều đó.
Kết luận
Khi hiểu cách React so sánh những thứ này, bạn sẽ biết khi nào React reuse component, khi nào nó remount component, và khi nào cần dùng key để kiểm soát hành vi đó. Hi vọng bài viết này sẽ giúp các bạn hiểu sâu hơn về React để từ đó làm việc với React tốt hơn. Đừng quên bình luận giúp mình để mình có thêm động lực viết bài nhen.




Quá bổ ích a ạ