React không giống như nhiều Javascript Framework khác, bởi thay vì làm việc với các DOM elements của trình duyệt, React tạo ra sự hiện diện ảo (virtual representation) của các DOM.
Với React, chúng ta không trực tiếp mô phỏng 1 DOM thật sự. Thay vào đó, chúng ta tạo ra sự mô phỏng ảo và để React xử lý công việc thay đổi các DOM trên trình duyệt.
Tại sao không sửa các DOM có sẵn?
Thông thường, khi chúng ta lập trình web cơ bản (như sử dụng jQuery), nó thường theo dạng thức:
- Tìm element, chẳng hạn sử dụng
.find(), hoặc vanilla javascript nhưdocument.querySelector()haydocument.getElementById(). - Sau đó, chỉnh sửa các element tìm được, như
.css(), hay.innerHTML()
Quá trình này có những vấn đề của nó:
- Thật khó để theo dõi thay đổi trạng thái hiện tại của element theo dạng thức ta cần.
- Nó có vẻ chậm hơn.
Thế nào là Virtual DOM?
Virtual DOM được sinh ra để xử lý những vấn đề trên.
Thực chất, Virtual DOM là 1 cây (tree) bao gồm các Javascript objects thay thế các DOM thực sự. Một trong những lý do thú vị nhất để sử dụng Virtual DOM là API. Khi sử dụng Virtual DOM chúng ta có thể khởi tạo lại DOM trong mỗi update.
Ý tưởng khởi tạo lại kết quả của DOM có vẻ khả thi và phù hợp với mô hình lập trình dễ hiểu: thay vì liên tục theo dõi sự thay đổi của DOM (vd .hasClass()), lập trình viên chỉ cần trả lại DOM mà anh ta muốn mọi người thấy. React sẽ lo phần thay đổi phía sau.
Virtual DOM sẽ:
- Sử dụng thuật toán so sánh thay đổi để biết những gì đã thay đổi
- Cập nhật danh mục DOM đồng thời
- Cập nhật hàng loạt vào DOM
Chính những điều đó sẽ giúp dễ sử dụng và tối ưu hoá để xây dựng web app hơn.
Đối tượng của Virtual DOM trong React
Virtual DOM của React là cây của ReactElement.
ReactElement
React sẽ lấy các ReactElement và đặt chúng vào các DOM thực sự cho chúng ta.
Một trong những cách tốt nhất để hiểu về ReactElement là sử dụng chúng trong trình duyệt, vậy hãy thử bắt đầu nhé!
Đầu tiên, bạn cần edit file index.html (có thể sử dụng basic template như thế này) bằng cách thêm 1 <div id="root"></div> trong thẻ <body>.
Bây giờ, chúng ta sẽ thử thêm các tag HTML như <b> vào trong DOM sử dụng React nhé.
Chúng ta sử dụng phương thức createElement được hỗ trợ bởi React, sẽ như sau:
var boldElement = React.createElement('b');
Mặc dù bạn đã khởi tạo, song nó là Virtual DOM nên sẽ không hiển thị cho tới khi bạn render nó vào trong cây DOM.
Render ReactElement
Để render element này vào cây DOM thực sự, bạn cần gọi tới phương thức ReactDOM.render(). Phương thức yêu cầu 2 tuỳ chọn: root của cây DOM ảo và nơi sẽ đặt các thành phần này vào.
Trong trường hợp hiện tại, chúng ta có sẵn <div> với id là root đã khởi tạo trong thẻ <body>, vì vậy chúng ta có thể xác định các thành phần như sau:
// Vanilla Javascript
var mountElement = document.getElementById('root');
// hoặc
var mountElement = document.querySelector('#root');
// jQuery
var mountElement = $('#root');
Với element đã lấy ở trên, ta có thể set React render:
var boldElement = React.createElement('b');
var mountElement = document.querySelector('#root');
ReactDOM.render(boldElement, mountElement);
Tất nhiên, mặc dù DOM đã hiển thị trong trình duyệt nhưng vẫn chưa có nội dung text nào hiện ra.
Thêm Text (với lớp con)
Như ở trên, React.createElement chỉ mới có 1 tuỳ chọn (chính là ‘b’ để tạo ra <b> tag). Tuy nhiên, React.createElement có thể chấp nhận tới 3 tuỳ chọn lần lượt là:
- Loại của DOM element (như thẻ H2, H3, strong)
- Trạng thái của element (props)
- Lớp đối tượng con (children)
Chúng ta sẽ tìm hiểu props sau, nên ta tạm set về null trong trường hợp này.
Lớp đối tượng con phải là đối tượng của ReactNode object, có thể là:
ReactElement- Một số hoặc giá trị (như
ReactText) - Một array của
ReactNodes
Lấy ví dụ, để thêm text vào trong boldElement ta tạo ở trên, chúng ta pass giá trị vào như sau:
var boldElement = React.createElement('b', null, 'Text ví dụ');
Lược dịch từ FullStackReact