Component là gì?
Component trong React đơn giản là một hàm JavaScript trả về JSX — một đoạn mô tả giao diện.- Tên component phải viết hoa chữ cái đầu —
Rating, không phảirating. React phân biệt component tự định nghĩa với thẻ HTML gốc chính bằng cách này. - Mỗi component nên có một file riêng — đặt trong thư mục
components/, tên file trùng với tên component (ví dụ:Rating.jsx).
components/Rating.jsx
App.jsx
Render danh sách với .map()
Khi cần render nhiều phần tử lặp lại — ví dụ 5 ngôi sao — bạn dùng .map() để biến một mảng thành danh sách JSX.
- Prop
keylà bắt buộc khi render danh sách. React dùng nó để theo dõi từng phần tử khi UI cập nhật. Nếu thiếu, bạn sẽ thấy warning trên console — và có thể gặp bug khó hiểu khi danh sách thay đổi. Dùng giá trị duy nhất, ổn định — ở đây làstar(1, 2, 3, 4, 5). - Không dùng
indexcủa.map()làmkeynếu danh sách có thể bị sắp xếp lại hoặc lọc bớt.
Styling Component
Có nhiều cách style trong React. Với component nhỏ nhưRating, hai cách phổ biến nhất là:
Inline style — dùng khi style đơn giản, không cần tách file:
className thay cho class (vì class là từ khóa trong JavaScript).
Styling với CSS Modules
CSS Modules thực ra khá phổ biến trong các dự án React, đặc biệt khi dùng với Vite hoặc Next.js vì được hỗ trợ sẵn, không cần cài thêm gì. Nó nằm giữa “inline style” (quá đơn giản) và Tailwind/styled-components (cần setup thêm). Nhiều team chọn nó vì tránh được xung đột class name mà vẫn viết CSS thuần. CSS Modules là cách viết CSS riêng cho từng component, trong đó tên class được tự động đổi thành duy nhất khi build — nên không bao giờ bị trùng với component khác, dù bạn đặt tên giống nhau.Rating.module.css
Rating.jsx
import styles from './Rating.module.css' trả về một object, mỗi class name là một key. Dùng styles.container thay vì "container".
Tên file phải có .module.css — đây là quy ước để bundler (Vite, webpack) nhận ra và xử lý class scoping tự động. File Rating.css bình thường sẽ không có tính năng này.
Khi build xong, class .star trong Rating.module.css sẽ thành tên kiểu _star_x7k2p_1 — unique, không đụng hàng với .star ở bất kỳ component nào khác.
Event Handler
Đây là phần quan trọng nhất trong bài, nơi component bắt đầu có tương tác.Cú pháp cơ bản
React dùng camelCase cho tên event, và nhận vào một hàm (không phải chuỗi như HTML thuần):Lưu ý quan trọng: có () hay không?
Đây là điểm dễ nhầm nhất:
() =>. Nếu không cần → truyền thẳng tên hàm.
Về bản chất đây là callback function.
Hãy nghĩ theo cách này: onClick chờ bạn truyền vào một hàm để gọi sau — tức là chỉ gọi khi có sự kiện xảy ra, không gọi ngay. Đó là định nghĩa của callback.
onClick={handleClick(star)} vì handleClick(star) gọi hàm ngay lập tức và trả về kết quả — thay vì truyền một hàm. Lúc này onClick nhận được undefined thay vì một callback.
Giải pháp là bọc trong một arrow function rỗng:
addEventListener trong Vanilla JS:
addEventListener cũng chờ nhận vào một hàm callback — truyền thẳng tên hàm nếu không có args, bọc trong arrow function nếu cần truyền args vào.
Ví dụ thực tế với Rating
onClick— xử lý click chuộtonMouseEnter— chuột di vào phần tửonMouseLeave— chuột rời khỏi phần tử
Lưu ý Best Practices
Đặt tên hàm xử lý event có prefixhandle — ví dụ handleClick, handleSubmit, handleChange. Giúp dễ phân biệt với các hàm logic khác.
Tách hàm handler ra ngoài JSX — đừng viết logic phức tạp trực tiếp trong onClick={...}. Khó đọc và khó debug.
Tóm tắt
Trong bài này, bạn đã nắm được:- Component là hàm trả về JSX, tên phải viết hoa, mỗi component nên có một file riêng.
- Render danh sách dùng
.map(), luôn kèm propkeyvới giá trị duy nhất và ổn định. - Styling có thể dùng inline style hoặc external CSS với
className. - Event Handler nhận vào một hàm (không gọi trực tiếp), dùng arrow function khi cần truyền tham số.
Rating của bạn thực sự hoạt động.