React là gì
React là một thư viện JavaScript được xây dựng và chủ yếu được duy trì bởi Facebook (Meta).
Cài đặt React
Cài đặt react: npm install react
Tạo phần tử HTML
document.createElement(tagName) là một Web API được các trình duyệt cung cấp để tạo một phần tử HTML.
React Element
Là khối xây dựng nhỏ nhất đại diện cho một đơn vị nhỏ trong giao diện người dùng.
React DOM
ReactDOM là sự kết hợp giữa React và DOM
Cài đặt React DOM
Cài đặt ReactDOM: npm install react-dom
Phần tử Root
Ứng dụng được xây dựng bằng React có một phần tử root duy nhất (Trường hợp sử dụng phổ biến nhất)
Giới thiệu về JSX
JSX có cú pháp giống HTML nhưng không phải là HTML
Attributes trong JSX
Thuộc tính trong JSX được truyền làm đối số thứ hai của React.createElement(...)
Làm việc với JSX
Vì JSX được chuyển đổi thành React.createElement(...) trả về một đối tượng, bạn có thể coi phần tử JSX như một đối tượng.
Biểu thức trong JSX
Biểu thức là bất kỳ đoạn code JavaScript hợp lệ nào có thể được tính toán thành một giá trị.
Attribute expression
Biểu thức thuộc tính là giá trị của thuộc tính được xác định dựa trên biểu thức (hoặc thường là biến)
Dynamic Value
Khi một trong các thuộc tính có một phần giá trị là động (thay đổi theo ngữ cảnh), bạn sẽ phải xem xét toàn bộ thuộc tính đó như là một giá trị hoàn toàn động
Children trong JSX
JSX cho phép định nghĩa các phần tử con bên trong phần tử cha
Thẻ tự đóng
Sử dụng cú pháp thẻ tự đóng cho các phần tử tự đóng trong JSX
JSX Fragments
Bạn có thể đóng gói nhiều phần tử bằng React.Fragment
Components
Component React là một hàm trả về một phần tử React mô tả một phần của giao diện người dùng.
Cách hoạt động của component
Component React là một hàm trả về Phần tử React
Xây dựng Components
Định nghĩa một component trong mỗi file riêng biệt để dễ gỡ lỗi code hơn
Props
Props là một đối tượng được truyền làm đối số đầu tiên của Component.
Props Children
props.children đại diện cho nội dung nằm giữa các thẻ của component.
Destructuring Props
Props là một đối tượng, vì vậy bạn có thể destructure props.
Pure function (Hàm thuần túy)
React yêu cầu các component là thuần túy để có thể cập nhật DOM một cách hiệu quả chỉ khi cần thiết.
Comment và kết xuất có điều kiện
Bạn có thể destructure từ hàm, miễn là hàm đó trả về một mảng phần tử.
Toán tử spread "..."
Toán tử spread (...) là một cú pháp cực kỳ hữu ích được giới thiệu từ ES6
Destructuring Array
Bạn có thể destructure từ hàm, miễn là hàm đó trả về một mảng phần tử.
Destructuring Function
Bạn có thể destructure từ hàm, miễn là hàm đó trả về một mảng phần tử.
State
Là trạng thái đề cập đến bất kỳ biến nào được định nghĩa bên trong Component với mục đích cập nhật sau này.
Import State
Để sử dụng State chúng ta phải tiến hành import hook useState
Khởi tạo State
Giá trị mặc định của State được trả về bởi useState sẽ giống với initialvalue truyền vào useState(initialvalue)
Update State
Chúng ta sẽ tìm hiểu cách cập nhật trạng thái và cách React & ReactDOM tự động cập nhật lại Component và hiển thị các cập nhật trên trình duyệt.
Áp dụng State
Áp dụng state cho chức năng counter
Closures
Closure là một khái niệm trong JavaScript nghe có vẻ phức tạp, nhưng trên thực tế thì nó khá đơn giản.
Event
Ta sử dụng onClick để gán sự kiện cho các phần tử trong JSX. Tuy nhiên, bạn chỉ nên thêm sự kiện này vào phần tử `` nhằm đảm bảo khả năng truy cập.
Quy ước đặt tên cho Event
Thay vì sử dụng sự kiện trực tiếp, ta chuyển sang sự kiện được đặt tên, cho phép xử lý những sự kiện phức tạp hơn bên trong
State & Event
Sau khi đã hiểu về event và closures, chúng ta có thể tiếp tục làm việc với state bên trong các component.
Update State theo điều kiện
Thay đổi trạng thái có điều kiện không phải là một khái niệm đặc thù của React mà thực tế là một yêu cầu cần thiết trong nhiều dự án.
Thay đổi State với Props
Trong React, Props và State là hai khái niệm cốt lõi để quản lý dữ liệu và điều khiển giao diện. Tuy nhiên, chúng có vai trò khác nhau — và việc “thay đổi State bằng Props” cần được hiểu đúng để tránh sai lầm trong thiết kế component.
Rendering theo điều kiện
Là một kỹ thuật hữu ích khi bạn muốn hiển thị các component khác nhau
Toán tử 3 ngôi
Có nhiều cách để kết xuất có điều kiện, chúng chủ yếu là các tính năng của JavaScript mà bạn có thể sử dụng trong React.
Toán tử AND
Toán tử logic && là cú pháp trong JavaScript cho phép bạn liên kết hai biểu thức với nhau.
Quy tắc gọi Hooks
Để hook hoạt động chính xác, bạn phải tuân theo hai quy tắc sau:
Array và Object
Trong JavaScript, Array là một object đặc biệt có thêm các phương thức và thuộc tính để quản lý danh sách có thứ tự.
Tính bất biến
Tính bất biến đề cập đến việc không thay đổi giá trị của dữ liệu sau khi đã được khởi tạo.
Ý nghĩa của tính bất biến
Mỗi khi bạn có một trạng thái của mảng hoặc đối tượng, chúng phải là bất biến.
Mảng bất biến
Khi làm việc với Mảng và Đối tượng, chúng ta cần chú trọng vào tính bất biến. Chúng ta sẽ tìm hiểu cách thêm, cập nhật và xóa các phần tử khỏi mảng theo cách bất biến (tức là không làm thay đổi mảng ban đầu).
Thao tác với mảng bất biến
Trong bài học này, chúng ta sẽ tìm hiểu cách cập nhật và xóa các phần tử từ mảng theo cách bất biến.
Array trong JSX
Trong JSX (cú pháp mở rộng của JavaScript dùng trong React), bạn có thể sử dụng mảng để hiển thị danh sách các phần tử một cách linh hoạt và hiệu quả.
Key trong React
Mỗi khi lặp qua map trong JSX, bạn cần cung cấp một key.
Thao tác bất biến với Object
Bây giờ chúng ta đã biết cách thay đổi mảng một cách bất biến (không làm thay đổi mảng ban đầu), do đó, việc thực hiện thao tác bất biến với đối tượng cũng trở nên dễ dàng hơn vì nó cũng dựa trên toán tử spread (...).
Loại bỏ key-value khỏi Object
Để xóa cặp key/value khỏi đối tượng mà không làm thay đổi đối tượng gốc, chúng ta cũng cần sử dụng toán tử spread nhưng với một cách tiếp cận khác.
Khai báo State là Object
Chúng ta sẽ làm việc với trạng thái đại diện cho đối tượng. Đừng quên rằng khi bạn muốn thay đổi một đối tượng trong JavaScript, bạn cần thực hiện sao cho không làm thay đổi đối tượng ban đầu!
Default Value
Khi bạn thiết lập value cho phần tử input trong React, giá trị đó sẽ không bao giờ thay đổi.
Thay đổi nội dung Input
Để thay đổi nội dung của một `` trong React, bạn cần sử dụng state để kiểm soát giá trị của input — đây chính là cách tạo một controlled component. Mỗi khi người dùng gõ vào input, bạn sẽ cập nhật state, và giá trị hiển thị trong input sẽ phản ánh đúng state đó.
Controlled component
Để kiểm soát một trường nhập liệu, bạn cần gán giá trị của nó cho một biến state và cập nhật biến state đó mỗi khi trường nhập liệu thay đổi.
Form Submit
Trong các dự án thực tế, form có thể có nhiều hơn một trường dữ liệu và chúng ta thường gặp các phần tử ` hoặc `.
Accessibility
Accessibility (Khả năng tiếp cận) là quá trình thiết kế và tạo ra các ứng dụng web có thể được sử dụng bởi mọi người.
Label
Trong React, cách sử dụng thẻ label có một số khác biệt nhỏ so với cách sử dụng thông thường, tương tự như việc sử dụng thuộc tính class trong React khác với cách sử dụng trong HTML thông thường.
Stateless và Stateful
Component React có thể được chia thành hai loại: stateless (không lưu trạng thái) hoặc stateful (lưu trạng thái). Sự khác biệt nằm ở việc component có xử lý State hay không.
Truyền Function vào Props
Chúng ta đã xem ví dụ về props chứa giá trị boolean, chuỗi, số, mảng và đối tượng. Ngoài ra, props cũng có thể chứa hàm.
Tái cấu trúc component
Việc tái cấu trúc component là một bước quan trọng trong phát triển ứng dụng React để cải thiện khả năng tái sử dụng, dễ bảo trì và mở rộng.
Lifting State Up
Lifting state up (nâng trạng thái của component con lên thành trạng thái của component cha).
Phân chia component
Khi xây dựng ứng dụng với React, bạn có thể gặp các component lớn chứa hàng trăm dòng code. Các component cần được tái cấu trúc và chia nhỏ thành các component nhỏ hơn.
Cải thiện hiệu suất của ứng dụng
Cập nhật state trong React là hành vi bất đồng bộ, tức là state không nhất thiết phải được cập nhật ngay lập tức.
Update State
Vì cập nhật trạng thái là hành vi bất đồng bộ, có một điều mà chúng ta cần phải để ý.
Effect
Hook useEffect được dùng để triển khai hiệu ứng (effect) trong component.
Tại sao nên dùng Effect
Bạn có thể đang tự hỏi, tại sao chúng ta cần sử dụng hook useEffect? Tại sao chúng ta không gọi document.title = "..." ở bất kỳ chỗ nào trong câu lệnh component trước câu lệnh return?
Clean Effect
Một số phương thức trong JavaScript yêu cầu việc dọn dẹp. Hãy cùng tìm hiểu lý do tại sao.
Clean Timer
Trong React, khi bạn sử dụng các hàm như setTimeout hoặc setInterval bên trong useEffect, bạn cần đảm bảo rằng chúng được dọn dẹp đúng cách để tránh rò rỉ bộ nhớ hoặc lỗi logic khi component được hiển thị lại hoặc bị gỡ bỏ khỏi DOM.
Effect Listeners
Chúng ta đã học cách thêm trình lắng nghe sự kiện vào phần tử bằng thuộc tính JSX onClick (hoặc tương tự). Tuy nhiên, nếu bạn muốn thêm một trình lắng nghe sự kiện vào đối tượng window thì phải làm thế nào?
Dependencies trong Effect
Dependencies là đối số thứ hai tùy chọn của hàm useEffect trong React, được truyền dưới dạng một mảng
Vòng đời Component qua useEffect
Hook useEffect trong React cho phép bạn xử lý các hiệu ứng phụ (side effects) như gọi API, tương tác với DOM, hoặc đăng ký sự kiện. Nó hoạt động tương tự như các phương thức vòng đời trong component dạng class, nhưng được sử dụng trong component hàm.
Có nên update State trong Effect
Nhìn chung, bạn được khuyến khích không nên cập nhật state từ bên trong useEffect.
Xây dựng component Clock
Các bước để xây dựng lên 1 component Clock
Sử dụng Effect với Conditional
Một trường hợp sử dụng phổ biến khác là chạy hiệu ứng khi một biến cụ thể được bật hoặc tắt.
Kết hợp Effect, State và Events
Khi sử dụng hiệu ứng, trạng thái và sự kiện cùng lúc, chúng ta có thể bị nhầm lẫn hoặc gặp khó khăn trong việc quản lý các tương tác giữa chúng.
Effect & Performance
Chúng ta đã sử dụng useEffect khá nhiều nhưng chưa thực sự tìm hiểu về ảnh hưởng của nó đến hiệu suất.
LocalStorage
LocalStorage là một API Web cho phép chúng ta lưu trữ các cặp khóa-giá trị trong trình duyệt.
Object trong LocalStorage
API localStorage chỉ hỗ trợ lưu trữ chuỗi dưới dạng khóa và giá trị, vì vậy, nếu bạn muốn lưu trữ arrays hoặc objects, bạn cần chuyển đổi chúng thành chuỗi.
Khôi phục State từ localStorage
Có nghĩa là giá trị khởi tạo mà ta cung cấp cho useState sẽ đến từ localStorage.
Storage Lazy
Trạng thái khởi tạo trễ giúp tránh các vấn đề về hiệu suất khi việc tính toán giá trị ban đầu cho trạng thái có thể tốn nhiều thời gian và tài nguyên.
Promises
Việc sử dụng promise là một yêu cầu cơ bản khi làm việc với Fetch API. Đây là một tính năng của ngôn ngữ JavaScript, do đó nó độc lập với React.
Fetch API
Fetch API là một API của trình duyệt (tức là một chức năng có sẵn trong trình duyệt) cho phép bạn thực hiện yêu cầu mạng đến máy chủ khác.
Fetch trong Component
Chúng ta đã học cách sử dụng fetch để lấy dữ liệu JSON từ backend/API. Chúng ta sẽ sử dụng fetch API bên trong component React và tạo một biến trạng thái từ dữ liệu nhận lại từ backend/API.
Fetch Error
Cố gắng truy cập vào một đối tượng/mảng được trả về từ API fetch trước khi fetch hoàn thành là một lỗi phổ biến khi sử dụng fetch.
Fetch API với toán tử logic &&
Đôi khi bạn không muốn hiển thị một JSX mới hoàn toàn mà chỉ muốn bỏ qua việc hiển thị một phần của JSX phụ thuộc vào data từ API.
Các loại lỗi khi Fetch API
Khi làm việc với API fetch, chúng ta có thể gặp một số vấn đề liên quan đến yêu cầu fetch. Hai loại lỗi phổ biến nhất là: lỗi HTTP và lỗi mạng.
Xử lý Loading khi Fetch API
Khi tải dữ liệu từ mạng bằng Fetch API, việc hiển thị trình tải (loader) là một phần quan trọng trong giao diện người dùng, đó là một chỉ báo hình ảnh cho người dùng biết rằng dữ liệu đang được tìm nạp từ mạng và họ nên đợi một chút.
Promise.finally
Là một phương thức được gọi sau khi một Promise đã kết thúc (dù thành công hay thất bại). Nó dùng để chạy một đoạn code "dọn dẹp" hoặc xử lý chung, mà không quan tâm kết quả của Promise
Fetch API với onClick
Một trường hợp sử dụng phổ biến của fetch là tải dữ liệu khi người dùng nhấp chuột vào nút.
Fetch khi thay đổi onChange
Một trường hợp sử dụng phổ biến khác của fetch là tải dữ liệu khi người dùng chọn một giá trị từ danh sách thả xuống.
Fetch với async/await
async/await là cú pháp rút gọn cho promise, cho phép bạn biểu diễn logic của promise như một tập hợp các hoạt động chạy tuần tự theo từng dòng. Nhưng đừng quên rằng async/await vẫn chạy các promise thực tế và gọi .then() cho bạn.
Fetch với async/await và xử lý lỗi
Việc sử dụng async/await trong sự kiện dễ dàng hơn so với việc sử dụng useEffect.
Post dữ liệu
Các cuộc gọi fetch mà ta đã thực hiện trong các chương trước là fetch GET. Ngược lại, POST thường được sử dụng để gửi thông tin cùng với yêu cầu fetch.
Custom Hooks
Chúng ta đã tìm hiểu về những hook được cung cấp bởi React useState, useEffect. Ngoài ra, React còn cung cấp một số hook khác. Tuy nhiên, điều thú vị là bạn có thể xây dựng các hook tùy chỉnh (custom hook) của riêng mình.
Custom Hooks useEffect
Trong bài học trước, chúng ta đã tìm hiểu về cách tạo custom hook. Bây giờ, chúng ta sẽ tìm hiểu về cách sử dụng custom hook với useEffect.
Di chuyển hooks vào file riêng
Mục tiêu của hook tùy chỉnh là tái sử dụng hook trong nhiều component. Việc đặt chúng vào một file riêng cũng giúp mã nguồn dễ đọc và dễ quản lý hơn.
Custom hooks với tham số
Vì hook tùy chỉnh là hàm nên chúng có thể nhận parameter. Bạn có thể cung cấp một hoặc nhiều tham số, thuộc bất kỳ kiểu dữ liệu nào, giống như các hàm thông thường.
Custom hooks với State
Hook tùy chỉnh có thể chứa các cuộc gọi useEffect, tương tự như thế, nó cũng có thể chứa các cuộc gọi useState. Vì vậy, bạn có thể tạo các biến state bên trong hook tùy chỉnh để tối ưu hóa và tái sử dụng logic chung một cách linh hoạt.
Custom useFetch Hook
Bạn có thể nhận thấy rằng code fetch thường rất dài, điều này làm cho component phức tạp hơn mức cần thiết. Đó là một trong những lý do tại sao chúng ta sẽ tạo hook tùy chỉnh useFetch để đơn giản hóa logic fetch Điều này cũng giúp chúng ta tránh những lỗi phổ biến khi làm việc với fetch, vì tất cả logic fetch đều được đặt trong hook tùy chỉnh useFetch.
Custom useFetch hooks với post
Trong bài học này, chúng ta sẽ tiếp tục viết hook tùy chỉnh useFetch bằng cách thêm một phương thức post.
Giới thiệu về Refs
Trong React, ref (viết tắt của reference) là một cơ chế cho phép bạn tạo ra một “tham chiếu” đến một DOM element hoặc một component, để có thể truy cập trực tiếp và thao tác với nó mà không cần thông qua props hay state.
Các bước tạo Refs
Trong bài học trước, chúng ta đã sử dụng ref để focus vào phần tử `` khi component App được hiển thị.
Giới thiệu về Context
Trong lập trình, từ "context" có thể được hiểu là thông tin liên quan. Đó cũng là cách Context được sử dụng trong React. Nó được sử dụng khi bạn muốn làm cho một số thông tin liên quan đến ứng dụng có thể được sử dụng trong nhiều component.
Khai báo Context
Trong React, Context là một cơ chế giúp truyền dữ liệu xuống nhiều cấp component mà không cần phải "props drilling" (truyền props qua từng cấp). Nó rất hữu ích khi bạn có dữ liệu dùng chung cho nhiều component, ví dụ như theme, ngôn ngữ, hoặc thông tin người dùng đăng nhập.
Sử dụng Context
Sau khi định nghĩa ThemeContext và ThemeProvider, chúng ta sẽ sử dụng chúng trong ứng dụng.
Giá trị Context
Giá trị của provider trong context không nhất thiết phải là chuỗi. Nó có thể là một mảng hoặc đối tượng.
Cập nhật giá trị Context
Giá trị của provider trong context không nhất thiết phải là chuỗi. Nó có thể là một mảng hoặc đối tượng.
Thuộc tính Component
Component là một “thành phần” trong hệ thống phần mềm hoặc lập trình, dùng để chia nhỏ chức năng phức tạp thành các khối độc lập, dễ quản lý và tái sử dụng. Trong ReactJS, thuộc tính Component chính là khái niệm cốt lõi để xây dựng giao diện người dùng theo dạng module
Render HTML thô
dangerouslySetInnerHTML là một thuộc tính đặc biệt trong React cho phép bạn chèn trực tiếp HTML thô vào bên trong component. Nó bỏ qua cơ chế tự động “escape” của React, vì vậy rất dễ dẫn đến lỗ hổng bảo mật XSS nếu dữ liệu không được kiểm soát.
Xuất nhiều component
Trong React, bạn có thể xuất nhiều component từ một file duy nhất. Điều này rất hữu ích khi bạn có nhiều component liên quan đến nhau và muốn nhóm chúng lại với nhau.
Thư viện clsx
clsx là một thư viện JavaScript nhỏ gọn (chỉ ~239 byte) dùng để kết hợp và xử lý chuỗi className trong React một cách linh hoạt, đặc biệt khi bạn cần gán class có điều kiện. Nó thường được dùng thay thế cho thư viện classnames vì nhanh hơn và nhẹ hơn.
React Router
React Router là một thư viện giúp tạo các route trong React dễ dàng hơn. Thư viện này không được xây dựng bởi đội ngũ phát triển React, do đó nó không phải là một gói React chính thức. Tuy nhiên, nó được sử dụng khá rộng rãi trong cộng đồng React.
Điều hướng cơ bản
Các thành phần chính của React Router là:
Route link
Ưu điểm của React Router là chúng ta có thể thực hiện điều hướng ngay tức thì. Đó là lý do tại sao chúng ta cần thay thế liên kết ` bằng component ` do React Router cung cấp.