Skip to content

Hiểu React từ gốc rễ qua biên dịch từ Vanilla JS

Từ Vanilla JS, thông qua Babel, đến JSX.
Hầu hết mọi người học React đều bắt đầu bằng Vite hoặc Create React App — chạy một lệnh, mọi thứ tự dựng lên, và bạn bắt đầu viết component luôn.
Tiện, nhưng có một vấn đề: bạn đang lái xe mà chưa biết động cơ hoạt động thế nào.
Bài này sẽ không dạy bạn cách dùng React nhanh nhất. Thay vào đó, chúng ta sẽ bắt đầu từ mức thấp nhất có thể — không build tool, không CLI — để hiểu React thực sự là gì trước khi các công cụ che đi sự phức tạp.

Bước 1: React thuần, không JSX

Cách đơn giản nhất để chạy React là dùng CDN — nhúng thẳng vào file HTML như bất kỳ thư viện JS nào khác.
Sau đó tạo component và render bằng JavaScript thuần:
React.createElement(tag, props, ...children) là hàm cốt lõi của React. Mọi component, mọi thẻ JSX bạn viết sau này — đều được biên dịch về hàm này.
Đây là mức thấp nhất, và bạn thấy ngay: nó rất dài dòng, khó đọc.

Bước 2: JSX ra đời để giải quyết vấn đề đó

JSX (JavaScript XML) là cú pháp mở rộng cho phép bạn viết HTML-like trực tiếp trong JavaScript. Thay vì:
Bạn viết:
Dễ đọc hơn rất nhiều. Nhưng JSX không phải JavaScript hợp lệ — browser không hiểu nó. Cần có một bước biên dịch (transpile) để chuyển JSX về React.createElement trước khi chạy.
Công cụ làm việc đó là Babel.

Bước 3: Thêm Babel để chạy JSX trên browser

Babel đọc type="text/babel", biên dịch JSX thành React.createElement, sau đó browser chạy bình thường. Đây là cách Vite và Next.js làm — chỉ là tự động hóa bước này đi.
⚠️ Cách dùng Babel qua CDN chỉ phù hợp để học và thử nghiệm. Không dùng cho production vì Babel biên dịch trực tiếp trên browser, gây chậm.

Những điều cần biết về JSX

1. Luôn có một root element

JSX bắt buộc phải được bọc trong một thẻ duy nhất ở ngoài cùng. Nếu không muốn thêm thẻ <div> thừa vào DOM, dùng Fragment:
<>...</> là viết tắt của <React.Fragment>...</React.Fragment>.

2. Component tự định nghĩa thì tự đóng

3. Nhúng JavaScript bằng {}

Bên trong JSX, dùng {} để chạy bất kỳ biểu thức JavaScript nào:
Lưu ý: {} chỉ nhận biểu thức (expression), không nhận câu lệnh (statement). Đó là lý do if/else thông thường không dùng được trực tiếp trong JSX — phải dùng ternary, hoặc tách ra ngoài:

4. Một số attribute phải đổi tên

Vì JSX chạy trong JavaScript, một số từ khóa bị trùng:
HTML
JSX
class
className
for
htmlFor
There are no rows in this table

Tóm tắt

Bản chất của React không thay đổi — JSX chỉ là lớp cú pháp bên trên React.createElement. Hiểu điều này giúp bạn không bị bối rối khi gặp lỗi biên dịch, và hiểu tại sao JSX lại có những quy tắc “kỳ lạ” như bắt buộc có root element hay không dùng được if trực tiếp.
Bước tiếp theo: khi đã hiểu nền tảng, chuyển sang dùng Vite để có môi trường phát triển thực sự — hot reload, module bundling, và không cần lo về Babel nữa.

Want to print your doc?
This is not the way.
Try clicking the ··· in the right corner or using a keyboard shortcut (
CtrlP
) instead.