diff --git a/README.de.md b/README.de.md index 26bde71..26111cb 100644 --- a/README.de.md +++ b/README.de.md @@ -1,6 +1,6 @@ **Read in other languages: [English 🇺🇸](README.en.md), [Polska 🇵🇱](README.pl.md), [German 🇩🇪](README.de.md), [French 🇫🇷](README.fr.md), -[Spanish 🇪🇸](README.es.md), [Українська 🇺🇦](README.md).** +[Spanish 🇪🇸](README.es.md), [Українська 🇺🇦](README.md), [Tiếng Việt 🇻🇳](README.vi.md).**

React diff --git a/README.en.md b/README.en.md index 32865e7..d45a9eb 100644 --- a/README.en.md +++ b/README.en.md @@ -1,6 +1,6 @@ **Read in other languages: [English 🇺🇸](README.en.md), [Polska 🇵🇱](README.pl.md), [German 🇩🇪](README.de.md), [French 🇫🇷](README.fr.md), -[Spanish 🇪🇸](README.es.md), [Українська 🇺🇦](README.md).** +[Spanish 🇪🇸](README.es.md), [Українська 🇺🇦](README.md), [Tiếng Việt 🇻🇳](README.vi.md).**

React diff --git a/README.es.md b/README.es.md index 6260ab4..04432bc 100644 --- a/README.es.md +++ b/README.es.md @@ -1,6 +1,6 @@ **Read in other languages: [English 🇺🇸](README.en.md), [Polska 🇵🇱](README.pl.md), [German 🇩🇪](README.de.md), [French 🇫🇷](README.fr.md), -[Spanish 🇪🇸](README.es.md), [Ukrainian 🇺🇦](README.md).** +[Spanish 🇪🇸](README.es.md), [Ukrainian 🇺🇦](README.md), [Tiếng Việt 🇻🇳](README.vi.md).**

React

diff --git a/README.fr.md b/README.fr.md index fcb6da1..5d3f0cd 100644 --- a/README.fr.md +++ b/README.fr.md @@ -1,6 +1,6 @@ **Read in other languages: [English 🇺🇸](README.en.md), [Polska 🇵🇱](README.pl.md), [German 🇩🇪](README.de.md), [French 🇫🇷](README.fr.md), -[Spanish 🇪🇸](README.es.md), [Українська 🇺🇦](README.md).** +[Spanish 🇪🇸](README.es.md), [Українська 🇺🇦](README.md), [Tiếng Việt 🇻🇳](README.vi.md).**

React diff --git a/README.md b/README.md index 5cbe7fc..b3d44c6 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ **Read in other languages: [English 🇺🇸](README.en.md), [Polska 🇵🇱](README.pl.md), [German 🇩🇪](README.de.md), [French 🇫🇷](README.fr.md), -[Spanish 🇪🇸](README.es.md), [Українська 🇺🇦](README.md).** +[Spanish 🇪🇸](README.es.md), [Українська 🇺🇦](README.md), [Tiếng Việt 🇻🇳](README.vi.md).**

React diff --git a/README.pl.md b/README.pl.md index 1427627..06a0692 100644 --- a/README.pl.md +++ b/README.pl.md @@ -1,6 +1,6 @@ **Read in other languages: [English 🇺🇸](README.en.md), [Polska 🇵🇱](README.pl.md), [German 🇩🇪](README.de.md), [French 🇫🇷](README.fr.md), -[Spanish 🇪🇸](README.es.md), [Українська 🇺🇦](README.md).** +[Spanish 🇪🇸](README.es.md), [Українська 🇺🇦](README.md), [Tiếng Việt 🇻🇳](README.vi.md).**

React diff --git a/README.vi.md b/README.vi.md new file mode 100644 index 0000000..14278d7 --- /dev/null +++ b/README.vi.md @@ -0,0 +1,4766 @@ +**Đọc bằng ngôn ngữ khác: [English 🇺🇸](README.en.md), +[Polska 🇵🇱](README.pl.md), [German 🇩🇪](README.de.md), [French 🇫🇷](README.fr.md), +[Spanish 🇪🇸](README.es.md), [Українська 🇺🇦](README.md), [Tiếng Việt 🇻🇳](README.vi.md).** + +

+ React +

+ +

Những câu hỏi phỏng vấn React phổ biến nhất và câu trả lời

+ +
+1. React là gì? + +#### React + +React là một thư viện JavaScript để xây dựng giao diện người dùng. Các đặc điểm chính: + +1. **Kiến trúc component:** Giao diện được chia thành các component độc lập có thể tái sử dụng. + +2. **Virtual DOM:** Đảm bảo cập nhật giao diện hiệu quả bằng cách giảm thiểu thao tác trên DOM thực. + +3. **Tính khai báo:** Bạn mô tả giao diện trông như thế nào ở một trạng thái nhất định, và React giữ nó đồng bộ. + +4. **Luồng dữ liệu một chiều:** Dữ liệu được truyền từ trên xuống qua props, giúp quản lý trạng thái dễ hơn. + +React được tạo ra bởi Facebook và được sử dụng rộng rãi để phát triển SPA (Single Page Application). + +
+ +
+2. Liệt kê các tính năng của React. + +#### React + +1. **Kiến trúc component:** Code được chia thành các component độc lập, có thể tái sử dụng. + +2. **Virtual DOM:** Cập nhật giao diện nhanh mà không cần thao tác trực tiếp trên DOM. + +3. **Luồng dữ liệu một chiều:** Dữ liệu được truyền từ component cha xuống component con qua props. + +4. **JSX:** Một phần mở rộng cú pháp JavaScript để viết giao diện dạng XML. + +5. **State và lifecycle:** Các component có thể lưu trữ và quản lý trạng thái riêng. + +6. **React Hooks:** Thêm khả năng quản lý trạng thái và side effect cho functional component. + +7. **Hệ sinh thái:** Hỗ trợ các thư viện như React Router và Redux để mở rộng chức năng. + +8. **Thân thiện với SEO (với Next.js):** Server-side rendering cải thiện việc index. + +9. **Phát triển mobile:** React Native cho phép xây dựng ứng dụng mobile dựa trên React. + +10. **Mã nguồn mở:** Được cộng đồng hỗ trợ tích cực. + +
+ +
+3. Các chức năng chính của React là gì? + +#### React + +#### Các chức năng chính của React: + +1. **Phương pháp khai báo:** React cho phép bạn xây dựng giao diện tương tác bằng cách mô tả nó trông như thế nào, trong khi thư viện tối ưu hóa việc cập nhật DOM. + +2. **Cấu trúc component:** Ứng dụng được xây dựng từ các component độc lập, có thể tái sử dụng, giúp đơn giản hóa việc phát triển, kiểm thử và bảo trì. + +3. **Virtual DOM:** React sử dụng Virtual DOM để cập nhật DOM thực một cách hiệu quả, cải thiện đáng kể hiệu suất. + +4. **Luồng dữ liệu một chiều:** Dữ liệu được truyền từ component cha xuống component con qua props, đơn giản hóa quản lý trạng thái. + +5. **Hooks:** Cho phép sử dụng trạng thái và lifecycle trong functional component. + +6. **JSX:** Phần mở rộng JavaScript để mô tả giao diện với cú pháp tương tự HTML. + +7. **React Native:** Khả năng xây dựng ứng dụng mobile native sử dụng cùng nguyên tắc như web. + +8. **Hệ sinh thái:** Bộ thư viện và công cụ lớn như React Router, Redux và Context API. + +9. **Hỗ trợ Server-side rendering (SSR):** Giúp tối ưu SEO và tăng tốc tải trang ban đầu. + +10. **Quản lý trạng thái:** Sử dụng `useState`, Context API, Redux hoặc các thư viện khác. + +Những tính năng này làm cho React trở thành thư viện mạnh mẽ và linh hoạt để xây dựng ứng dụng hiện đại. + +
+ +
+4. Những ưu điểm chính khi sử dụng React là gì? + +#### React + +#### Ưu điểm chính khi sử dụng React + +1. **Tốc độ**: Nhờ Virtual DOM, React giảm thiểu tương tác với DOM thực, cải thiện hiệu suất. + +2. **Kiến trúc component**: Code được chia thành các component tái sử dụng, đơn giản hóa phát triển và bảo trì. + +3. **Luồng dữ liệu một chiều**: Dữ liệu trong React chảy một chiều (từ trên xuống), giúp debug dễ hơn. + +4. **Cộng đồng lớn**: React có hệ sinh thái khổng lồ gồm thư viện, công cụ và extension. + +5. **Tương thích với phát triển mobile**: Sử dụng React Native, bạn có thể xây dựng ứng dụng mobile đa nền tảng. + +6. **JSX**: Cú pháp cho phép viết JavaScript cùng với markup giống HTML, cải thiện khả năng đọc code. + +7. **Hỗ trợ Hooks**: Đơn giản hóa làm việc với trạng thái và lifecycle trong functional component. + +8. **Thân thiện với SEO**: Server-side rendering với các công cụ như Next.js cải thiện SEO. + +9. **Tính linh hoạt**: React có thể tích hợp vào bất kỳ dự án hoặc framework nào mà không cần thay đổi code đáng kể. + +10. **React DevTools**: Công cụ debug tiện lợi để kiểm tra component và trạng thái ứng dụng. + +
+ +
+5. JSX là gì? + +#### React + +**JSX (JavaScript XML)** là cú pháp cho phép bạn viết cấu trúc giao diện dạng XML bên trong JavaScript. JSX là phần mở rộng của JavaScript và được sử dụng trong React để mô tả giao diện trông như thế nào. + +#### Các tính năng chính của JSX: + +1. **Cú pháp giống XML:** Trông giống HTML nhưng được dùng trong JavaScript. + +```jsx +const element = Hello, world!; +``` + +2. **JavaScript nhúng:** Bạn có thể viết code JavaScript bên trong dấu ngoặc nhọn `{}`. + +```jsx +const name = 'Alice'; +const element = Hello, {name}!; +``` + +3. **Biên dịch:** JSX được biên dịch thành JavaScript thông thường bằng các thư viện như Babel. + +```jsx +const element = Hello; +// Trở thành: +const element = React.createElement('h1', null, 'Hello'); +``` + +4. **Thuộc tính:** Được sử dụng tương tự HTML, nhưng thay vì `class` viết `className`, và thay vì `for` viết `htmlFor`. + +```jsx +const input = ; +``` + +5. **JSX trả về cây phần tử:** Một biểu thức JSX chỉ có thể trả về một phần tử gốc. Dùng `` hoặc thẻ rỗng `<>` để nhóm. + +```jsx +return <>Title Description; +``` + +#### Ưu điểm: + +- Tạo UI component thuận tiện. +- Cú pháp rõ ràng và dễ đọc. +- Tích hợp chặt chẽ với logic JavaScript. + +JSX không bắt buộc trong React, nhưng được sử dụng rộng rãi vì sự tiện lợi và linh hoạt. + +
+ +
+6. Sự khác biệt giữa state và props là gì? + +#### React + +#### Sự khác biệt giữa state và props + +| Tiêu chí | State | Props | +| -------------------- | ----------------------------------------------------------- | ----------------------------------------------------------- | +| **Mục đích** | Lưu trữ trạng thái nội bộ của component. | Truyền dữ liệu từ component cha xuống component con. | +| **Khả năng thay đổi** | Có thể thay đổi bên trong component. | Bất biến (chỉ đọc). | +| **Phạm vi** | Chỉ có trong component nơi nó được định nghĩa. | Có sẵn trong component con qua thuộc tính. | +| **Khởi tạo** | Được đặt bên trong component bằng `useState` hoặc constructor. | Được định nghĩa bởi component cha. | +| **Phạm vi sử dụng** | Dùng để lưu dữ liệu động có thể thay đổi. | Dùng để truyền dữ liệu cố định hoặc động. | +| **Ai kiểm soát?** | Component nơi trạng thái được định nghĩa. | Component cha. | + +
+ +
+7. Sự khác biệt giữa element và component là gì? + +#### React + +#### Sự khác biệt giữa element và component trong React: + +| Tiêu chí | Element | Component | +| ------------------- | ------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- | +| **Định nghĩa** | Một đối tượng mô tả giao diện trông như thế nào. | Một hàm hoặc class trả về các React element. | +| **Loại** | Bất biến. | Có thể tái sử dụng và có thể có trạng thái. | +| **Cú pháp tạo** | `React.createElement` hoặc JSX (`
`). | Hàm hoặc class (`function MyComponent() {}` hoặc `class MyComponent extends React.Component {}`). | +| **Mục đích** | Đại diện cho một node trong DOM. | Đóng gói logic và cấu trúc giao diện. | +| **Cách dùng** | Dùng để tạo giao diện ở mức cơ bản. | Dùng để xây dựng cấu trúc phức tạp hơn với business logic. | +| **Ví dụ** | `

Hello

` | `function Hello() { return

Hello

; }` | + +Element là "khối xây dựng," trong khi component là "bộ tạo" để tạo ra giao diện phức tạp. + +
+ +
+8. Làm thế nào để tạo component trong React? + +#### React + +#### Trong React, component có thể được tạo theo hai cách: + +1. **Functional component:** Là một hàm đơn giản trả về các React element. + +```jsx +function Greeting(props) { + return Hello, {props.name}!; +} + +// Cách dùng: +; +``` + +2. **Class component:** Là một class extends `React.Component` và phải có phương thức `render`. + +```jsx +class Greeting extends React.Component { + render() { + return Hello, {this.props.name}!; + } +} + +// Cách dùng: +; +``` + +#### Sự khác biệt: + +- Functional component đơn giản hơn và phù hợp hơn cho các component không có trạng thái. + +- Class component được dùng cho các component phức tạp hơn với trạng thái riêng hoặc lifecycle methods. + +**Lưu ý:** Cách tiếp cận hiện đại là sử dụng functional component với hooks thay vì class component. + +
+ +
+9. State trong React là gì? + +#### React + +**State** trong React là một đối tượng dùng để lưu dữ liệu có thể thay đổi theo thời gian và ảnh hưởng đến cách component được render. State cho phép React component trở nên động và phản hồi với các sự kiện, đầu vào người dùng và nhiều hơn nữa. + +#### Đặc điểm của state: + +1. **Cục bộ với component:** State chỉ có trong component nơi nó được định nghĩa. + +2. **Thay đổi bất đồng bộ:** React gộp các lần gọi `setState` để tối ưu rendering. + +3. **Được khởi tạo trong constructor** (với class component) hoặc với `useState` (trong functional component). + +#### Trong class component: + +```jsx +class Counter extends React.Component { + constructor(props) { + super(props); + this.state = { count: 0 }; + } + + increment = () => { + this.setState({ count: this.state.count + 1 }); + }; + + render() { + return ( + + Count: {this.state.count} + Increment + + ); + } +} +``` + +#### Trong functional component (với hook `useState`): + +```jsx +import React, { useState } from 'react'; + +function Counter() { + const [count, setCount] = useState(0); + + return ( + + Count: {count} +
+ +
+10. Props trong React là gì? + +#### React + +**Props** trong React là một đối tượng chứa dữ liệu được truyền từ component cha xuống component con. Chúng được dùng để cấu hình component và bất biến. + +#### Đặc điểm của props: + +1. **Truyền từ trên xuống** (luồng dữ liệu một chiều) từ component cha xuống component con. + +2. **Bất biến**: Component không thể thay đổi props mà nó nhận. + +3. **Động**: Giá trị props có thể thay đổi nếu dữ liệu trong component cha thay đổi. + +#### Sử dụng props: + +1. **Trong functional component:** + +```jsx +function Welcome(props) { + return Hello, {props.name}!; +} + +// Cách dùng: +; +``` + +2. **Trong class component:** + +```jsx +class Welcome extends React.Component { + render() { + return Hello, {this.props.name}!; + } +} + +// Cách dùng: +; +``` + +#### Truyền props: + +```jsx +function App() { + return ( + + ); +} +``` + +**Kết quả:** + +```bash +Hello, Alice! +Hello, Bob! +``` + +#### Destructuring props: + +```jsx +function Welcome({ name }) { + return Hello, {name}!; +} +``` + +#### Giá trị mặc định của props: + +```jsx +function Welcome({ name = 'Guest' }) { + return Hello, {name}!; +} + +// Cách dùng: +; // Xuất ra: Hello, Guest! +``` + +Props cung cấp sự linh hoạt và khả năng tái sử dụng cho React component. + +
+ +
+11. Tại sao cần thuộc tính `key` khi render danh sách? + +#### React + +Thuộc tính `key` được dùng để xác định các phần tử trong danh sách khi render. + +#### Mục đích: + +1. **_Tối ưu hóa cập nhật:_** React dùng `key` để cập nhật giao diện hiệu quả bằng cách xác định nhanh các phần tử cần thay đổi, thêm hoặc xóa. + +2. **_Ngăn render không cần thiết:_** `key` giúp tránh render lại các phần tử không thay đổi. + +3. **_Bảo toàn trạng thái component:_** Ví dụ, nếu một mục danh sách chứa form, `key` cho phép React bảo toàn trạng thái của nó giữa các lần cập nhật. + +#### Cách dùng đúng: + +- Giá trị `key` phải là duy nhất trong các phần tử cùng cấp. + +- Các định danh ổn định hoạt động tốt nhất (ví dụ: `id` từ database). + +- Không nên dùng chỉ số mảng làm `key`, vì điều này có thể gây lỗi khi thứ tự phần tử thay đổi. + +```jsx +const items = ['Apple', 'Banana', 'Cherry']; +return ( + + {items.map((item, index) => ( + {item} // Key duy nhất cho mỗi phần tử + ))} + +); +``` + +
+ +
+12. Dữ liệu được truyền giữa các component trong React như thế nào? + +#### React + +Trong React, dữ liệu được truyền giữa các component theo phân cấp như sau: + +#### Truyền dữ liệu xuống (từ cha xuống con) + +Props được dùng để truyền dữ liệu xuống. Component cha truyền giá trị hoặc hàm cho component con qua thuộc tính. + +**Ví dụ:** + +```jsx +function ParentComponent() { + const data = 'Hello from Parent'; + + return; +} + +function ChildComponent({ message }) { + return { message }; +} +``` + +`message` truyền giá trị `data` cho component con `ChildComponent`. + +Trong component con, props được truy cập qua tham số hàm hoặc qua `this.props` trong class component. + +#### Truyền dữ liệu lên (từ con lên cha) + +Dữ liệu được truyền lên bằng hàm callback. Component cha truyền một hàm cho con, và con gọi nó với dữ liệu cần thiết. + +**Ví dụ:** + +```jsx +function ParentComponent() { + const handleData = childData => { + console.log('Data from child:', childData); + }; + + return ; +} + +function ChildComponent({ sendData }) { + const data = 'Hello from Child'; + + return
+ +
+13. Tại sao React dùng `className` thay vì thuộc tính `class`? + +#### React + +React dùng `className` thay vì `class` vì `class` là từ khóa dành riêng trong JavaScript. + +#### Lý do: + +1. **Tránh xung đột**: `class` được dùng để định nghĩa class trong JavaScript (`class MyComponent {}`), có thể gây lỗi cú pháp. + +2. **Tương thích JSX**: JSX là phần mở rộng cú pháp của JavaScript, nên dùng `className` tránh nhầm lẫn. + +3. **Ánh xạ trực tiếp** trong `document.createElement`: React chuyển đổi JSX thành lời gọi `React.createElement`, và `className` được dùng để đặt class cho các phần tử DOM. + +#### Ví dụ: + +```jsx +// Đúng trong React + +Hello; + +// Sai (lỗi cú pháp) + +Hello; +``` + +Đây là tiêu chuẩn của React đảm bảo tính ổn định và nhất quán trong code. + +
+ +
+14. Những quy tắc đặt tên và ngoại lệ nào tồn tại cho React component? + +#### React + +Trong React, có một số quy tắc và ngoại lệ quan trọng về tên component: + +1. **Chữ hoa cho component:** Tên component phải bắt đầu bằng chữ hoa. Điều này cần thiết để React phân biệt component với các phần tử HTML tiêu chuẩn. + +Ví dụ: + +- Đúng: `` +- Sai: `` + +2. **CamelCase:** Nên dùng CamelCase cho tên component. Điều này có nghĩa là mỗi từ mới trong tên component bắt đầu bằng chữ hoa: + +- `MyComponent` +- `UserProfile` + +3. **Tên không trùng với phần tử HTML:** Không dùng tên component trùng với các thẻ HTML tiêu chuẩn như `div`, `span`, `button`, v.v. Điều này có thể gây xung đột và hành vi không mong muốn: + +- Đúng: `` +- Sai: `
+ +
+15. Làm thế nào để viết comment trong React? + +#### React + +Trong React, comment được viết giống như trong JavaScript, nhưng có một số điểm khác biệt khi dùng trong JSX. + +1. **Comment trong JavaScript (bên ngoài JSX)** + +```javascript +// Comment một dòng + +/* +Comment nhiều dòng +*/ +``` + +2. **Comment bên trong JSX** + +- Trong JSX, bạn cần dùng cú pháp đặc biệt vì JSX là một phần của JavaScript. + +- Comment trong JSX phải được viết bên trong dấu ngoặc nhọn `{}`: + +```jsx +function MyComponent() { + return ( + + {/_ Đây là comment bên trong JSX _/} + Hello, world! + + ); +} +``` + +- Comment trong JSX phải được bọc trong `{/* comment */}`, nếu không sẽ gây lỗi. + +- Chúng chỉ có thể dùng bên trong biểu thức JSX. + +3. **Comment trong hàm và phương thức** + +- Đối với comment bên trong hàm hoặc phương thức, bạn có thể dùng comment JavaScript tiêu chuẩn: + +```jsx +function MyComponent() { + // Đây là nơi chúng ta render component + return Hello, world!; +} +``` + +#### Tóm tắt: + +- Trong JSX, dùng `{/* comment */}`. + +- Trong JavaScript thông thường, dùng `//` cho comment một dòng và `/* ... */` cho comment nhiều dòng. + +
+ +
+16. Virtual DOM trong React là gì? + +#### React + +**Virtual DOM** là biểu diễn ảo của DOM thực mà React sử dụng để cập nhật giao diện hiệu quả. + +#### Cách hoạt động trong React: + +1. **Render vào Virtual DOM:** Khi trạng thái hoặc props của component thay đổi, React cập nhật Virtual DOM. + +2. **Diffing:** React so sánh Virtual DOM mới với phiên bản cũ, xác định tập hợp thay đổi tối thiểu. + +3. **Cập nhật DOM thực:** Các thay đổi được phát hiện được áp dụng lên DOM thực, giảm thiểu số lượng thao tác. + +#### Ưu điểm chính: + +Tối ưu hóa cập nhật DOM, cải thiện đáng kể hiệu suất ứng dụng. + +
+ +
+17. Prop `key` là gì và lợi ích của nó khi dùng trong mảng phần tử? + +#### React + +Trong React, prop `key` được dùng để xác định mỗi phần tử trong danh sách hoặc mảng, giúp React quản lý render hiệu quả khi các mục danh sách thay đổi hoặc được cập nhật. + +#### Các điểm quan trọng về `key`: + +1. **Tính duy nhất:** Mỗi phần tử trong danh sách phải có `key` duy nhất. Điều này cho phép React theo dõi phần tử nào đang thay đổi, được thêm vào hoặc bị xóa, đồng thời bảo toàn trạng thái của chúng giữa các lần render. + +2. **Tối ưu hóa render:** Dùng `key` cho phép React giảm số lần render lại bằng cách chỉ thực hiện các thay đổi cần thiết lên DOM. Không có `key`, React khó theo dõi thay đổi hơn, có thể dẫn đến render lại toàn bộ danh sách kể cả khi chỉ một mục thay đổi. + +3. **Bản chất của `key`:** Prop `key` không được truyền vào component, nên không thể dùng để hiển thị giá trị trong giao diện. Đây là thuộc tính nội bộ chỉ React dùng để theo dõi phần tử. + +#### Ví dụ dùng `key` trong danh sách: + +```jsx +const items = ['apple', 'banana', 'cherry']; + +function FruitList() { + return ( + + {items.map((item, index) => ( + {item} // Quan trọng: dùng key duy nhất + ))} + + ); +} +``` + +#### Tầm quan trọng của tính duy nhất của `key`: + +- **Cách dùng sai:** Nếu dùng các giá trị không duy nhất làm key (ví dụ: cùng một index), React sẽ không theo dõi thay đổi đúng, dẫn đến lỗi render. + +- **Key lý tưởng:** Thường nếu có định danh duy nhất cho phần tử (ví dụ: id), nên dùng nó làm key thay vì index mảng. + +```jsx +const items = [ + { id: 1, name: 'apple' }, + { id: 2, name: 'banana' }, + { id: 3, name: 'cherry' }, +]; + +function FruitList() { + return ( + + {items.map(item => ( + {item.name} // Tốt hơn là dùng id duy nhất + ))} + + ); +} +``` + +#### Lợi ích khi dùng `key`: + +- Cải thiện hiệu suất render. + +- Cho phép React chỉ cập nhật tối ưu các phần tử đã thay đổi thay vì toàn bộ danh sách. + +- Đảm bảo xử lý đúng trạng thái phần tử khi các mục bị di chuyển, xóa hoặc cập nhật. + +
+ +
+18. Conditional rendering trong React là gì? + +#### React + +Conditional rendering trong React là quá trình component render nội dung khác nhau tùy thuộc vào điều kiện nhất định. Điều này cho phép thay đổi động những gì component hiển thị dựa trên trạng thái, props hoặc các yếu tố khác. + +#### Các cách tiếp cận chính để conditional rendering: + +1. **Toán tử `if`:** Bạn có thể dùng toán tử `if` tiêu chuẩn để quyết định render gì. + +```jsx +function Greeting(props) { + if (props.isLoggedIn) { + return Welcome back!; + } + return Please sign up.; +} +``` + +2. **Toán tử ternary:** Toán tử ternary thường được dùng cho biểu thức điều kiện ngắn hơn. + +```jsx +function Greeting(props) { + return {props.isLoggedIn ? 'Welcome back!' : 'Please sign up.'}; +} +``` + +3. **Toán tử AND logic (`&&`) để render:** Bạn có thể dùng toán tử `&&` để render một phần tử chỉ khi biểu thức bên trái là truthy. + +```jsx +function Notifications(props) { + return ( + + {props.unreadMessages.length > 0 && ( + You have {props.unreadMessages.length} unread messages. + )} + + ); +} +``` + +4. **Dùng `return` với toán tử điều kiện:** Bạn có thể dùng `return` cho conditional rendering dựa trên các điều kiện khác nhau, như trong ví dụ với `if` hoặc toán tử ternary. + +#### Ưu điểm của conditional rendering: + +- Cho phép nội dung thay đổi động tùy thuộc vào trạng thái hoặc props. + +- Cải thiện tính linh hoạt và khả năng hiển thị nội dung khác nhau cho người dùng hoặc tình huống khác nhau. + +#### Ví dụ: + +```jsx +function UserStatus(props) { + return ( + + {props.isLoggedIn ? ( + Log Out + ) : ( + Log In + )} + + ); +} +``` + +Ở đây nút thay đổi tùy thuộc vào việc người dùng đã đăng nhập hay chưa. + +
+ +
+19. Fragment trong React là gì? + +#### React + +Fragment trong React là cách nhóm nhiều phần tử mà không thêm phần tử phụ vào DOM. Chúng cho phép trả về nhiều phần tử từ một component mà không cần wrapper như `div`, giúp tránh các phần tử không cần thiết có thể làm hỏng styles hoặc cấu trúc tài liệu. + +#### Fragment được dùng như thế nào? + +1. **Không có Fragment (với wrapper):** + +```jsx +function MyComponent() { + return ( + + Title + Some text + + ); +} +``` + +Trong ví dụ này, một `div` duy nhất bọc `h1` và `p` được trả về. + +2. **Với Fragment (không có wrapper):** + +```jsx +function MyComponent() { + return <>Title Some text; +} +``` + +Bây giờ `h1` và `p` được render mà không có container thêm, giúp giữ DOM sạch. + +#### Ưu điểm: + +- **DOM sạch:** Bạn có thể tránh các wrapper không cần thiết trong DOM. + +- **Tiện cho render nhiều phần tử:** Bạn có thể trả về nhiều phần tử từ một component mà không cần wrapper thêm. + +#### Cú pháp: + +- Bạn có thể dùng thẻ rỗng `<>` và ``, là viết tắt của ``. + +- Bạn cũng có thể dùng `React.Fragment` nếu cần thêm key (ví dụ khi render danh sách): + +```jsx +{ + item.name; +} +{ + item.description; +} +``` + +#### Khi nào nên dùng: + +- Khi cần render nhiều phần tử mà không có wrapper thêm trong DOM. + +- Khi muốn bảo toàn cấu trúc component mà không ảnh hưởng đến styles hoặc layout. + +Fragment rất hữu ích để giảm các phần tử DOM không cần thiết và cải thiện hiệu suất. + +
+ +
+20. Reconciliation là gì? + +#### React + +**Reconciliation** là quá trình React dùng để cập nhật DOM theo cách hiệu quả nhất. Khi trạng thái hoặc props của component thay đổi, React tính toán các thay đổi tối thiểu cần thực hiện trên DOM thực để đồng bộ hóa với trạng thái của virtual DOM. + +#### Reconciliation hoạt động như thế nào? + +1. **So sánh virtual DOM cũ và mới:** + +- React giữ bản sao của virtual DOM trước đó. +- Khi trạng thái hoặc props thay đổi, virtual DOM mới được tạo ra. +- React so sánh virtual DOM mới với bản sao trước đó (thuật toán diffing). + +2. **Phát hiện sự khác biệt (diffing):** + +- React xác định những phần nào của cây đã thay đổi (phần tử mới, thay đổi thuộc tính hoặc xóa phần tử). +- Để làm điều này, nó dùng thuật toán được tối ưu hóa cho cấu trúc dạng cây. + +3. **Cập nhật DOM thực:** + +- React chỉ áp dụng thay đổi cho các phần DOM cần cập nhật, tránh render lại toàn bộ. + +#### Nguyên tắc chính của reconciliation: + +- **Bảo toàn các node cùng cấp:** Nếu các node có cùng kiểu (ví dụ: `
` vẫn là `
`), React chỉ thay đổi thuộc tính và phần tử con. +- **Tái sử dụng component:** Nếu component vẫn giữ nguyên, React tái sử dụng instance component hiện có. +- **Key cho danh sách:** Nếu danh sách phần tử được render từ mảng, React dùng key (prop `key`) để so sánh và bảo toàn các node. + +#### Ví dụ: + +```jsx +function App({ isVisible }) { + return isVisible ? Hello : Goodbye; +} +``` + +- Nếu `isVisible` thay đổi từ `true` thành `false`, React sẽ xóa `

` và thay thế bằng `

`. + +#### Tầm quan trọng của key (prop `key`) cho danh sách: + +Key giúp React xác định đúng các thay đổi trong danh sách. Ví dụ: + +```jsx + + {items.map(item => ( + {item.text} + ))} + +``` + +Không có key duy nhất, React sẽ không thể xác định chính xác phần tử danh sách nào đã thay đổi. + +#### Ưu điểm của reconciliation: + +- Giảm số lượng thao tác DOM. +- Cải thiện hiệu suất ứng dụng. +- Cung cấp cập nhật giao diện mượt mà. + +

+ +
+21. Làm thế nào để cập nhật trạng thái của component? + +#### React + +Trong React, trạng thái component được cập nhật bằng phương thức `setState` trong class component hoặc `useState` trong functional component. + +#### Class component: + +Trạng thái được cập nhật qua `this.setState()`. + +#### Ví dụ: + +```jsx +class Counter extends React.Component { + constructor(props) { + super(props); + this.state = { count: 0 }; + } + + increment = () => { + this.setState({ count: this.state.count + 1 }); + }; + + render() { + return ( + + Count: {this.state.count} + Increment + + ); + } +} +``` + +#### Functional component: + +Trạng thái được cập nhật qua hàm trả về bởi `useState`. + +#### Ví dụ: + +```jsx +import React, { useState } from 'react'; + +function Counter() { + const [count, setCount] = useState(0); + + const increment = () => { + setCount(count + 1); + }; + + return ( + + Count: {count} + Increment + + ); +} +``` + +#### Lưu ý: + +1. **Bất đồng bộ:** `setState` và `useState` hoạt động bất đồng bộ. Để cập nhật trạng thái dựa trên giá trị trước đó, dùng cách tiếp cận hàm: + +```jsx +this.setState(prevState => ({ count: prevState.count + 1 })); +setCount(prevCount => prevCount + 1); +``` + +2. **Không cập nhật trạng thái trực tiếp:** Sửa đổi trạng thái mà không dùng `setState` hoặc `useState` không kích hoạt render lại. + +
+ +
+22. Inline conditional expression là gì? + +#### React + +**Inline conditional expression** trong JavaScript (bao gồm React) là các cơ chế cho phép nhúng điều kiện trực tiếp vào JSX để render có điều kiện các phần tử hoặc component. Điều này làm cho code ngắn gọn và dễ hiểu hơn. + +#### Các phương pháp chính: + +1. **Toán tử điều kiện (toán tử ternary):** Đây là một trong những cách phổ biến nhất để render có điều kiện trong JSX. + +```jsx +condition ? expression_if_true : expression_if_false; +``` + +**Ví dụ:** + +```jsx +const isLoggedIn = true; + +function App() { + return {isLoggedIn ? 'Welcome, User!' : 'Please log in'}; +} +``` + +2. **Toán tử AND logic (`&&`):** Phương pháp này cho phép hiển thị component hoặc phần tử chỉ khi điều kiện là `true`. Nếu điều kiện không thỏa, không có gì được render. + +**Ví dụ:** + +```jsx +const isUserAdmin = true; + +function App() { + return {isUserAdmin && You have admin privileges}; +} +``` + +Trong trường hợp này, `

You have admin privileges

` chỉ hiển thị nếu `isUserAdmin` là `true`. + +3. **`if` trước khi trả về JSX:** Bạn cũng có thể dùng câu lệnh `if` thông thường trước khi trả về JSX khi điều kiện phức tạp hơn. + +**Ví dụ:** + +```jsx +function App() { + let content; + if (isLoggedIn) { + content = Welcome back!; + } else { + content = Please sign in.; + } + + return {content}; +} +``` + +**Ưu điểm:** + +- Inline conditional expression cho phép viết code sạch và ngắn gọn hơn. + +- Chúng cải thiện khả năng đọc và giảm nhu cầu cho các cấu trúc điều kiện phụ. + +#### Quan trọng: + +- Trong React, bạn không thể dùng câu lệnh `if` trực tiếp bên trong JSX. Tuy nhiên, bạn có thể dùng chúng trước khi trả về JSX. + +
+ +
+23. Sự khác biệt giữa xử lý sự kiện trong HTML và React là gì? + +#### React + +#### Sự khác biệt giữa xử lý sự kiện trong HTML và React: + +| Tiêu chí | HTML | React | +| -------------------------- | ---------------------------------------------------------------- | --------------------------------------------------------------------------- | +| **Gắn sự kiện** | Được chỉ định là thuộc tính: `
+ +
+24. Synthetic event trong React là gì? + +#### React + +**Synthetic event** trong React là wrapper bao quanh các sự kiện DOM native cung cấp giao diện nhất quán để xử lý sự kiện trên các browser khác nhau. React tạo ra `SyntheticEvent` cho mỗi sự kiện, cho phép xử lý sự kiện theo cách thống nhất, đảm bảo tương thích cross-browser và cải thiện hiệu suất. + +#### Đặc điểm chính: + +1. **Tương thích cross-browser:** `SyntheticEvent` trừu tượng hóa hành vi sự kiện đặc thù của browser và cung cấp hành vi nhất quán. + +2. **Tối ưu hóa:** `SyntheticEvent` dùng object pooling giúp giảm chi phí tạo đối tượng sự kiện mới. + +3. **Dùng một lần:** Sau khi sự kiện được xử lý, đối tượng `SyntheticEvent` được "trả lại" pool và không thể dùng sau đó. Đối với thao tác bất đồng bộ, sự kiện nên được lưu vào biến riêng. + +4. **Giao diện:** `SyntheticEvent` có cùng phương thức với sự kiện native tiêu chuẩn (ví dụ: `preventDefault()` và `stopPropagation()`). + +#### Ví dụ: + +```jsx +function handleClick(event) { + // SyntheticEvent cung cấp quyền truy cập phương thức preventDefault() + event.preventDefault(); + console.log('Button clicked!'); +} + +function App() { + return Click me; +} +``` + +Trong ví dụ này, `event` là `SyntheticEvent` hoạt động tương tự sự kiện native nhưng với khả năng cải tiến. + +
+ +
+25. Làm thế nào để xử lý sự kiện trong React? + +#### React + +Trong React, xử lý sự kiện hoạt động tương tự JavaScript tiêu chuẩn, nhưng có một số điểm khác biệt. Các sự kiện trong React là synthetic, nghĩa là chúng cung cấp abstraction trên các sự kiện browser thực và đảm bảo tương thích cross-browser. + +#### Nguyên tắc chính xử lý sự kiện trong React: + +1. **Synthetic event:** Tất cả sự kiện trong React được bọc trong đối tượng **SyntheticEvent**, là implementation cross-browser của các sự kiện DOM tiêu chuẩn. + +2. **Dùng camelCase cho sự kiện:** Trong React, sự kiện được viết theo camelCase thay vì chữ thường (ví dụ: `onClick` thay vì `onclick`). + +3. **Truyền hàm làm event handler:** Sự kiện trong React được xử lý bằng hàm truyền qua thuộc tính component. + +#### Ví dụ xử lý sự kiện `click`: + +```jsx +import React, { Component } from 'react'; + +class MyButton extends Component { + handleClick = () => { + alert('Button clicked!'); + }; + + render() { + return Click Me; + } +} + +export default MyButton; +``` + +#### Ví dụ với functional component: + +```jsx +import React, { useState } from 'react'; + +function MyButton() { + const [count, setCount] = useState(0); + + const handleClick = () => { + setCount(count + 1); + }; + + return Clicked {count} times; +} + +export default MyButton; +``` + +#### Đặc điểm xử lý sự kiện: + +1. **Không cần dùng `addEventListener`:** Trong React, không cần thêm hoặc xóa event handler thủ công. Điều này được quản lý tự động bởi thư viện React. + +2. **Bảo toàn context trong phương thức class component:** Nếu phương thức class component được dùng làm event handler, context `this` phải được bind bằng arrow function hoặc thủ công trong constructor. + +```jsx +class MyComponent extends React.Component { + constructor(props) { + super(props); + this.state = { count: 0 }; + // Binding phương thức + this.handleClick = this.handleClick.bind(this); + } + + handleClick() { + this.setState({ count: this.state.count + 1 }); + } + + render() { + return ( + + Clicked {this.state.count} times + + ); + } +} +``` + +3. **Truyền tham số cho hàm handler:** Nếu cần truyền thêm đối số cho event handler, bạn có thể dùng arrow function hoặc hàm có tham số. + +```jsx +function MyButton({ label }) { + const handleClick = (event, label) => { + console.log(label); + }; + + return
+ +
+26. Pointer Event là gì? + +#### React + +#### Pointer Event trong React + +**Pointer Event** là API thống nhất các sự kiện chuột, cảm ứng và bút stylus thành một hệ thống xử lý sự kiện duy nhất. + +#### Các Pointer Event chính + +| **Sự kiện** | **Mô tả** | +| ------------------- | ------------------------------------------------------------------------ | +| **onPointerDown** | Kích hoạt khi nhấn bằng ngón tay, chuột hoặc bút stylus. | +| **onPointerUp** | Kích hoạt khi thả nút chuột, ngón tay hoặc bút stylus. | +| **onPointerMove** | Kích hoạt khi con trỏ di chuyển trên phần tử. | +| **onPointerEnter** | Kích hoạt khi con trỏ vào trong phạm vi phần tử. | +| **onPointerLeave** | Kích hoạt khi con trỏ rời khỏi phạm vi phần tử. | +| **onPointerCancel** | Kích hoạt khi browser hủy sự kiện (ví dụ: khi thay đổi focus). | + +#### Ví dụ trong React + +```jsx +const PointerExample = () => { + const handlePointerDown = () => console.log('Pointer pressed'); + + return ( + + Click here + + ); +}; +``` + +Code này sẽ log `"Pointer pressed"` vào console khi nhấn bằng bất kỳ thiết bị nào (chuột, cảm ứng hoặc bút stylus). + +
+ +
+27. Khi nào nên dùng class component thay vì functional component? + +#### React + +Class component từng được dùng khi cần một hoặc nhiều tính năng sau: + +1. **Làm việc với state:** Trước đây, functional component không hỗ trợ local state, nên class được dùng cho mục đích này. Ngày nay, hook (`useState`, `useReducer`) cho phép functional component làm việc với state. + +2. **Lifecycle method:** Class cung cấp quyền truy cập các phương thức như `componentDidMount`, `componentDidUpdate` và `componentWillUnmount` để quản lý component ở các giai đoạn khác nhau. Ngày nay, điều này được xử lý bởi hook `useEffect`. + +3. **Xử lý logic phức tạp:** Nếu logic cần nhiều phương thức và truy cập thuộc tính qua `this`, class có vẻ là lựa chọn logic. Cách tiếp cận hiện đại là hook, cho phép đóng gói logic. + +#### Khi class không còn cần thiết: + +Bắt đầu từ React 16.8, functional component với hook thay thế nhu cầu cho class component. Vì vậy, trong các dự án mới, nên ưu tiên functional component. Class chủ yếu được dùng để duy trì legacy code. + +
+ +
+28. Stateless component là gì? + +#### React + +Stateless component là các component không lưu trữ hoặc quản lý bất kỳ internal state nào. Chúng chỉ nhận dữ liệu qua props và hiển thị nó dưới dạng giao diện. Thường thì các component này là functional. + +#### Đặc điểm: + +1. **Không có state:** Chúng không dùng `this.state` và không thay đổi internal state. + +2. **Chỉ render:** Chúng đơn giản nhận props và hiển thị chúng dưới dạng UI element. + +3. **Đơn giản và dễ dự đoán:** Dễ kiểm thử và bảo trì hơn vì không cần theo dõi thay đổi trạng thái. + +#### Ví dụ: + +```jsx +// Stateless component +function Greeting(props) { + return Hello, {props.name}!; +} + +// Cách dùng: +; +``` + +#### Ưu điểm: + +- **Đơn giản:** Dễ hiểu và bảo trì. + +- **Tối ưu hiệu suất:** Vì các component này không có state, React có thể cập nhật chúng hiệu quả hơn. + +#### Khi nào nên dùng: + +- Khi component đơn giản chỉ hiển thị dữ liệu và không cần thay đổi. + +
+ +
+29. Stateful component là gì? + +#### React + +**Stateful component** là các component lưu trữ và quản lý internal state. Chúng dùng state để lưu dữ liệu có thể thay đổi theo thời gian, và những thay đổi này ảnh hưởng đến việc render component. + +#### Đặc điểm: + +1. **State:** Chúng dùng `this.state` để lưu và quản lý dữ liệu có thể thay đổi. + +2. **Phương thức cập nhật state:** Chúng dùng phương thức `this.setState()` để cập nhật state. + +3. **Lifecycle:** Chúng có quyền truy cập các lifecycle method như `componentDidMount()`, `shouldComponentUpdate()`, `componentDidUpdate()`, v.v. + +#### Ví dụ: + +```jsx +// Stateful component +class Counter extends React.Component { + constructor(props) { + super(props); + this.state = { + count: 0, + }; + } + + increment = () => { + this.setState({ count: this.state.count + 1 }); + }; + + render() { + return ( + + {this.state.count} + Increment + + ); + } +} +``` + +#### Ưu điểm: + +- **Component động:** Chúng có thể thay đổi nội dung và giao diện dựa trên thay đổi trạng thái. + +- **Tương tác:** Phù hợp để xây dựng giao diện tương tác nơi state cần được cập nhật để phản hồi tương tác người dùng. + +#### Khi nào nên dùng: + +Khi component cần quản lý internal state, ví dụ để lưu đầu vào form, bộ đếm, lựa chọn, v.v. + +
+ +
+30. Pure Component là gì? + +#### React + +**Pure Component** là các React class component đặc biệt tự động tối ưu hóa render. Chúng thực hiện so sánh shallow của props và state để ngăn các cập nhật không cần thiết nếu giá trị props hoặc state không thay đổi. + +#### Làm thế nào để tạo Pure Component? + +Pure Component được tạo bằng cách extends `React.PureComponent`. + +```jsx +import React, { PureComponent } from 'react'; + +class MyComponent extends PureComponent { + render() { + return Hello, {this.props.name}!; + } +} + +// Cách dùng: +; +``` + +#### `PureComponent` hoạt động như thế nào? + +- Nó thực hiện so sánh shallow của props và state trong phương thức `shouldComponentUpdate`. + +- Nếu props và state không thay đổi, component không render lại. + +#### Khi nào nên dùng `PureComponent`? + +- Khi props và state là các cấu trúc đơn giản (giá trị primitive hoặc đối tượng shallow). + +- Để cải thiện hiệu suất trong các component cập nhật thường xuyên. + +#### Hạn chế: + +1. **So sánh sâu:** `PureComponent` không tính đến thay đổi bên trong đối tượng hoặc mảng lồng nhau. Ví dụ, nếu bạn cập nhật đối tượng nhưng tham chiếu vẫn không thay đổi, component sẽ không cập nhật. + +```jsx +this.setState({ data: { ...this.state.data, key: 'new value' } }); // Cách giải quyết +``` + +2. **Không hoạt động với functional component:** Thay thế là dùng `React.memo` để tối ưu functional component. + +```jsx +const MyComponent = React.memo(function MyComponent(props) { + return Hello, {props.name}!; +}); +``` + +
+ +
+31. Higher-Order Component (HOC) là gì? + +#### React + +**Higher-Order Component** là một hàm nhận component làm đối số đầu vào và trả về component mới, mở rộng chức năng của nó. + +#### Cú pháp HOC: + +```jsx +const EnhancedComponent = higherOrderComponent(WrappedComponent); +``` + +#### Đặc điểm HOC: + +1. **Nhận component làm đối số.** +2. **Trả về component mới với props hoặc hành vi bổ sung.** +3. **Cho phép tái sử dụng logic trong các component khác nhau.** + +#### Ví dụ: + +HOC để thêm state vào component: + +```jsx +import React, { useState } from 'react'; + +// HOC: thêm logic state +function withCounter(WrappedComponent) { + return function EnhancedComponent(props) { + const [count, setCount] = useState(0); + + const increment = () => setCount(count + 1); + + return ; + }; +} + +// Component được nâng cấp +function Button({ count, increment }) { + return Clicked {count} times; +} + +// Cách dùng HOC +const EnhancedButton = withCounter(Button); + +export default EnhancedButton; +``` + +#### Các trường hợp dùng HOC thực tế: + +1. **Xác thực:** Bọc component để kiểm tra quyền truy cập. + +2. **Xử lý dữ liệu:** Kết nối với API hoặc xử lý state. + +3. **Logging:** Thêm logging cho các hành động component. + +#### Hạn chế của HOC: + +- Có thể tạo nesting sâu trong cây component nếu dùng quá nhiều HOC. + +- Có thể giảm khả năng đọc vì wrapper component thêm vào. + +HOC là công cụ mạnh để tái sử dụng logic, nhưng trong ứng dụng hiện đại thường được thay thế bởi React Hooks. + +
+ +
+32. Prop `children` là gì? + +#### React + +#### Prop `children` là gì? + +`children` là prop đặc biệt trong React được dùng để truyền các phần tử hoặc component lồng nhau vào component wrapper. + +#### Cách hoạt động? + +Khi bạn truyền nội dung con giữa thẻ mở và đóng của component, nội dung đó tự động được truyền dưới dạng `props.children`. + +#### Ví dụ: + +- **Component wrapper:** + +```jsx +function Wrapper({ children }) { + return { children }; +} +``` + +- **Cách dùng:** + +```jsx +function App() { + return ( + + Hello, World! + This is a paragraph inside the wrapper. + + ); +} +``` + +- **Kết quả:** + +```html +Hello, World! This is a paragraph inside the wrapper. +``` + +#### Các tính năng chính của `children`: + +1. **Linh hoạt:** Bạn có thể truyền bất kỳ loại dữ liệu nào: văn bản, JSX, component hoặc mảng phần tử. + +2. **Tái sử dụng:** Component wrapper có thể render động các nội dung khác nhau. + +3. **Composition có cấu trúc:** Giúp tạo component với cấu trúc lồng nhau. + +#### Dùng `children` với function prop: + +Đôi khi `children` được dùng như một hàm để truyền dữ liệu động: + +```jsx +function List({ items, children }) { + return {items.map(item => children(item))}; +} + +function App() { + return ( + + {item => {item}} + + ); +} +``` + +#### Kết quả: + +```html +Apple Banana Cherry +``` + +`children` là công cụ mạnh để tạo component toàn dụng và tái sử dụng trong React. + +
+ +
+33. Portal là gì? + +#### React + +**Portal** trong React là cách render các phần tử con vào DOM node tồn tại bên ngoài phân cấp DOM của component cha. + +#### Cách hoạt động: + +React cung cấp portal qua phương thức `ReactDOM.createPortal`, nhận hai đối số: + +1. **React element** để render. + +2. **DOM node đích** nơi phần tử sẽ được chèn vào. + +#### Cú pháp: + +```jsx +ReactDOM.createPortal(child, container); +``` + +- **`child`** là React element để render. + +- **`container`** là DOM node nơi phần tử sẽ được chèn. + +#### Ví dụ: + +```jsx +import React from 'react'; +import ReactDOM from 'react-dom'; + +function Modal({ children }) { + return ReactDOM.createPortal( + {children}, + document.getElementById('modal-root') // Node đích + ); +} + +function App() { + return ( + + Main content + + This is modal content + + + + ); +} +``` + +#### Nơi portal được dùng: + +- Modal. + +- Tooltip. + +- Context menu. + +#### Đặc điểm: + +1. **Phân cấp sự kiện:** Mặc dù phần tử được render bên ngoài phân cấp DOM, xử lý sự kiện vẫn theo phân cấp React component. Ví dụ, sự kiện `onClick` sẽ bubble lên component React cha. + +2. **Linh hoạt:** Portal cho phép chèn phần tử vào những nơi không phù hợp với cấu trúc DOM hiện tại. + +#### Ưu điểm: + +- Quản lý dễ các phần tử "nổi". +- Bảo toàn React context kể cả bên ngoài phân cấp DOM chính. + +
+ +
+ +34. Portal hoạt động như thế nào trong React và ưu điểm, trường hợp dùng UI chính là gì? + +#### React + +**Portal** trong React cho phép render các phần tử con vào một phần khác của DOM thay vì vị trí render mặc định của component. Điều này hữu ích để đặt các phần tử nên tồn tại bên ngoài phân cấp DOM thông thường, như modal, tooltip hoặc phần tử nổi. + +#### Ưu điểm chính của portal: + +- Cho phép render phần tử ở nơi khác trong DOM mà không làm hỏng cấu trúc React component. + +- Hữu ích khi phần tử cần được render phủ lên nội dung khác (ví dụ modal hoặc menu pop-up). + +#### Cách portal hoạt động: + +- Portal cho phép gửi nội dung đến bất kỳ nơi nào trong DOM, kể cả bên ngoài React container gốc. + +#### Ví dụ portal: + +```jsx +import ReactDOM from 'react-dom'; + +const Modal = () => { + return ReactDOM.createPortal( +
+

This is a modal window

+
, + document.getElementById('modal-root') // DOM node nơi portal được render + ); +}; + +const App = () => { + return ( +
+

Main page

+ +
+ ); +}; +``` + +#### Các điểm chính: + +- `ReactDOM.createPortal()` được dùng để tạo portal. Đối số đầu tiên là nội dung để render, đối số thứ hai là DOM element mà nội dung đó được chèn vào. + +- Portal có thể dùng cho modal, tooltip, menu pop-up và các phần tử khác cần hiển thị bên ngoài cây component chính. + +#### Đặc điểm: + +- Mặc dù các phần tử được render qua portal nằm bên ngoài phân cấp React component chính, chúng vẫn có quyền truy cập context, state và props của component cha. + +- Portal hữu ích khi phần tử cần được đặt "phía trên" nội dung khác hoặc ở cấp phân cấp DOM khác (ví dụ modal không bị giới hạn bởi container cha). + +Portal cho phép bảo toàn logic và cấu trúc component mà không vi phạm quy tắc DOM, giúp tạo ra UI component sạch và tiện dụng. + +
+ +
+35. Các lifecycle method của component trong React là gì? + +#### React + +Các lifecycle method của component trong React được dùng để quản lý các giai đoạn khác nhau của vòng đời component: tạo, cập nhật và xóa. + +#### Các giai đoạn lifecycle chính: + +1. **Mounting:** Khi component được thêm vào DOM. + +`constructor()`: Khởi tạo state và bind phương thức. + +`static getDerivedStateFromProps(props, state)`: Cập nhật state trước render (ít dùng). + +`render()`: Render JSX vào virtual DOM. + +`componentDidMount()`: Gọi ngay sau khi component được thêm vào DOM. Dùng cho API request và khởi tạo thư viện. + +2. **Updating:** Khi props hoặc state thay đổi. + +`static getDerivedStateFromProps(props, state)`: Gọi trước mỗi lần render. + +`shouldComponentUpdate(nextProps, nextState)`: Kiểm soát liệu component có nên render lại hay không. Mặc định trả về `true`. + +`render()`: Chạy để cập nhật virtual DOM. + +`getSnapshotBeforeUpdate(prevProps, prevState)`: Lấy snapshot trước thay đổi (ví dụ: vị trí scroll). + +`componentDidUpdate(prevProps, prevState, snapshot)`: Gọi sau khi cập nhật. Dùng cho request lặp lại hoặc làm việc với DOM. + +3. **Unmounting:** Khi component bị xóa khỏi DOM. + +`componentWillUnmount()`: Dùng để dọn dẹp tài nguyên (ví dụ: timer hoặc subscription). + +4. **Xử lý lỗi:** Khi component throw lỗi. + +`static getDerivedStateFromError(error)`: Cho phép cập nhật state sau lỗi. + +`componentDidCatch(error, info)`: Log lỗi. + +
+ +
+36. useEffect hook là gì và cách dùng? + +#### React + +`useEffect` là hook React cho phép thực hiện side effect trong functional component. Side effect bao gồm các thao tác như fetch dữ liệu, đăng ký subscription, đặt timer, thay đổi DOM trực tiếp, v.v. + +#### Cú pháp: + +```jsx +useEffect(() => { + // Code side effect + return () => { + // Cleanup (tùy chọn) + }; +}, [dependencies]); +``` + +#### Ví dụ cơ bản: + +```jsx +import React, { useState, useEffect } from 'react'; + +function Timer() { + const [seconds, setSeconds] = useState(0); + + useEffect(() => { + const interval = setInterval(() => { + setSeconds(prev => prev + 1); + }, 1000); + + return () => clearInterval(interval); // Cleanup + }, []); // Mảng dependency rỗng = chạy một lần khi mount + + return

Seconds: {seconds}

; +} +``` + +#### Mảng dependency: + +- **`[]`** — Effect chạy một lần khi mount. +- **`[value]`** — Effect chạy lại khi `value` thay đổi. +- **Không có mảng** — Effect chạy sau mỗi lần render. + +
+ +
+37. useState hook là gì? + +#### React + +`useState` là hook cơ bản trong React cho phép thêm local state vào functional component. + +#### Cú pháp: + +```jsx +const [state, setState] = useState(initialValue); +``` + +- `state` — Giá trị trạng thái hiện tại. +- `setState` — Hàm để cập nhật trạng thái. +- `initialValue` — Giá trị ban đầu của trạng thái. + +#### Ví dụ: + +```jsx +import React, { useState } from 'react'; + +function Counter() { + const [count, setCount] = useState(0); + + return ( +
+

Count: {count}

+ + +
+ ); +} +``` + +#### Lưu ý: + +- Gọi `setState` kích hoạt render lại component. +- `useState` có thể dùng nhiều lần trong một component. +- Để cập nhật dựa trên giá trị trước: `setCount(prev => prev + 1)`. + +
+ +
+38. useCallback hook là gì? + +#### React + +`useCallback` là hook trả về phiên bản được memoize của hàm callback. Nó chỉ tạo lại hàm khi các dependency thay đổi. + +#### Cú pháp: + +```jsx +const memoizedCallback = useCallback(() => { + doSomething(a, b); +}, [a, b]); +``` + +#### Khi nào dùng: + +- Khi truyền callback xuống component con được tối ưu (dùng `React.memo`). +- Khi hàm được dùng làm dependency trong `useEffect`. + +#### Ví dụ: + +```jsx +import React, { useState, useCallback } from 'react'; + +function Parent() { + const [count, setCount] = useState(0); + + const handleClick = useCallback(() => { + setCount(prev => prev + 1); + }, []); // Hàm được tạo một lần + + return ; +} + +const Child = React.memo(({ onClick }) => { + return ; +}); +``` + +
+ +
+39. useMemo hook là gì? + +#### React + +`useMemo` là hook trả về giá trị được memoize từ một tính toán tốn kém. Nó chỉ tính toán lại khi dependency thay đổi. + +#### Cú pháp: + +```jsx +const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]); +``` + +#### Ví dụ: + +```jsx +import React, { useState, useMemo } from 'react'; + +function ExpensiveComponent({ list }) { + const [filter, setFilter] = useState(''); + + const filteredList = useMemo(() => { + return list.filter(item => item.includes(filter)); + }, [list, filter]); // Chỉ tính lại khi list hoặc filter thay đổi + + return ( +
+ setFilter(e.target.value)} /> + +
+ ); +} +``` + +#### Khác biệt với `useCallback`: + +- `useMemo` memoize **giá trị** (kết quả của hàm). +- `useCallback` memoize **hàm** (bản thân hàm đó). + +
+ +
+40. useRef hook là gì? + +#### React + +`useRef` là hook trả về đối tượng ref có thể thay đổi với thuộc tính `.current`. Không giống state, thay đổi ref **không** kích hoạt render lại. + +#### Cú pháp: + +```jsx +const refContainer = useRef(initialValue); +``` + +#### Hai cách dùng chính: + +1. **Truy cập DOM element:** + +```jsx +function TextInput() { + const inputRef = useRef(null); + + const focusInput = () => { + inputRef.current.focus(); + }; + + return ( + <> + + + + ); +} +``` + +2. **Lưu giá trị có thể thay đổi (không gây render lại):** + +```jsx +function Timer() { + const intervalRef = useRef(null); + + const start = () => { + intervalRef.current = setInterval(() => console.log('tick'), 1000); + }; + + const stop = () => { + clearInterval(intervalRef.current); + }; + + return ( + <> + + + + ); +} +``` + +
+ +
+41. useContext hook là gì? + +#### React + +`useContext` là hook cho phép functional component đăng ký vào React context mà không cần bọc bằng Consumer component. + +#### Cú pháp: + +```jsx +const value = useContext(MyContext); +``` + +#### Ví dụ: + +```jsx +import React, { createContext, useContext } from 'react'; + +// Tạo context +const ThemeContext = createContext('light'); + +function ThemedButton() { + const theme = useContext(ThemeContext); + return ; +} + +function App() { + return ( + + + + ); +} +``` + +#### Khi nào dùng: + +- Chia sẻ dữ liệu toàn cục (theme, người dùng đã đăng nhập, ngôn ngữ) giữa nhiều component. +- Tránh "prop drilling" (truyền props qua nhiều cấp component). + +
+ +
+42. Context API là gì? + +#### React + +**Context API** là cơ chế tích hợp trong React cho phép chia sẻ dữ liệu giữa các component mà không cần truyền props qua từng cấp trong cây component (tránh "prop drilling"). + +#### Các thành phần chính: + +1. **`React.createContext()`** — Tạo context object. +2. **`Context.Provider`** — Cung cấp giá trị cho cây component con. +3. **`useContext()`** — Hook để đọc giá trị context trong functional component. + +#### Ví dụ: + +```jsx +import React, { createContext, useContext, useState } from 'react'; + +const UserContext = createContext(null); + +function App() { + const [user, setUser] = useState({ name: 'Alice' }); + + return ( + + + + ); +} + +function Profile() { + const user = useContext(UserContext); + return

Hello, {user.name}!

; +} +``` + +#### Khi nào dùng Context vs. Redux: + +- **Context API** — Phù hợp cho dữ liệu đơn giản, ít thay đổi (theme, locale, user). +- **Redux/Zustand** — Phù hợp cho state phức tạp, nhiều thao tác, cần middleware. + +
+ +
+43. Custom Hook là gì? + +#### React + +**Custom Hook** là hàm JavaScript bắt đầu bằng `use` và có thể gọi các hook khác. Chúng cho phép trích xuất và tái sử dụng logic stateful giữa các component. + +#### Ví dụ: + +```jsx +import { useState, useEffect } from 'react'; + +// Custom Hook để fetch dữ liệu +function useFetch(url) { + const [data, setData] = useState(null); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + + useEffect(() => { + fetch(url) + .then(res => res.json()) + .then(data => { + setData(data); + setLoading(false); + }) + .catch(err => { + setError(err.message); + setLoading(false); + }); + }, [url]); + + return { data, loading, error }; +} + +// Cách dùng +function UserList() { + const { data, loading, error } = useFetch('/api/users'); + + if (loading) return

Loading...

; + if (error) return

Error: {error}

; + + return ; +} +``` + +#### Quy tắc: + +- Tên phải bắt đầu bằng `use`. +- Chỉ gọi hook ở cấp cao nhất (không trong vòng lặp, điều kiện). +- Chỉ gọi hook từ React function component hoặc custom hook khác. + +
+ +
+44. Redux là gì? + +#### React + +**Redux** là thư viện quản lý state có thể dự đoán được cho ứng dụng JavaScript. Thường dùng với React để quản lý trạng thái ứng dụng toàn cục. + +#### Các khái niệm cốt lõi: + +1. **Store** — Chứa toàn bộ trạng thái ứng dụng. +2. **Action** — Object mô tả điều gì đã xảy ra (`{ type: 'INCREMENT' }`). +3. **Reducer** — Hàm thuần túy nhận state + action, trả về state mới. +4. **Dispatch** — Gửi action đến store. +5. **Selector** — Hàm đọc state từ store. + +#### Luồng dữ liệu: + +``` +UI → dispatch(action) → reducer(state, action) → new state → UI update +``` + +#### Ví dụ cơ bản: + +```jsx +import { createStore } from 'redux'; + +// Reducer +function counterReducer(state = { count: 0 }, action) { + switch (action.type) { + case 'INCREMENT': + return { count: state.count + 1 }; + case 'DECREMENT': + return { count: state.count - 1 }; + default: + return state; + } +} + +// Store +const store = createStore(counterReducer); + +store.dispatch({ type: 'INCREMENT' }); +console.log(store.getState()); // { count: 1 } +``` + +#### Khi nào dùng Redux: + +- Ứng dụng lớn với nhiều component cần cùng truy cập state. +- State phức tạp với nhiều thao tác. +- Cần debuggability tốt (Redux DevTools). + +
+ +
+45. React.memo là gì? + +#### React + +`React.memo` là Higher-Order Component (HOC) memoize functional component, ngăn render lại nếu props không thay đổi. + +#### Cú pháp: + +```jsx +const MemoizedComponent = React.memo(MyComponent); +``` + +#### Ví dụ: + +```jsx +import React from 'react'; + +const ExpensiveChild = React.memo(({ name, count }) => { + console.log('Child rendered'); + return
{name}: {count}
; +}); + +function Parent() { + const [count, setCount] = React.useState(0); + const [other, setOther] = React.useState(0); + + return ( +
+ + + + {/* Click "Change other" sẽ không render lại ExpensiveChild */} +
+ ); +} +``` + +#### So sánh custom: + +```jsx +const MemoizedComponent = React.memo(MyComponent, (prevProps, nextProps) => { + return prevProps.id === nextProps.id; // true = không render lại +}); +``` + +
+ +
+46. Lazy loading trong React là gì? + +#### React + +**Lazy loading** là kỹ thuật tải component chỉ khi cần thiết, thay vì tải tất cả khi ứng dụng khởi động. Điều này giảm kích thước bundle ban đầu và cải thiện thời gian tải trang. + +#### Sử dụng `React.lazy` và `Suspense`: + +```jsx +import React, { Suspense } from 'react'; + +// Component được tải lazily +const LazyComponent = React.lazy(() => import('./LazyComponent')); + +function App() { + return ( +
+ Loading...
}> + + + + ); +} +``` + +#### Lưu ý: + +- `React.lazy` chỉ hỗ trợ default export. +- `Suspense` là bắt buộc để hiển thị fallback trong khi component đang tải. +- Thường kết hợp với React Router để lazy load theo route. + +
+ +
+47. Error Boundary là gì? + +#### React + +**Error Boundary** là React component bắt lỗi JavaScript trong cây component con, log chúng và hiển thị fallback UI thay vì làm crash toàn bộ ứng dụng. + +#### Cách tạo: + +```jsx +class ErrorBoundary extends React.Component { + constructor(props) { + super(props); + this.state = { hasError: false }; + } + + static getDerivedStateFromError(error) { + return { hasError: true }; + } + + componentDidCatch(error, errorInfo) { + console.error('Error caught:', error, errorInfo); + } + + render() { + if (this.state.hasError) { + return

Something went wrong.

; + } + return this.props.children; + } +} + +// Cách dùng +function App() { + return ( + + + + ); +} +``` + +#### Giới hạn: + +Error Boundary **không** bắt lỗi trong: +- Event handler (dùng `try/catch`). +- Async code (setTimeout, Promise). +- Server-side rendering. +- Bản thân Error Boundary. + +
+ +
+48. Strict Mode trong React là gì? + +#### React + +**Strict Mode** là công cụ phát triển giúp phát hiện các vấn đề tiềm ẩn trong ứng dụng React. Không ảnh hưởng đến production build. + +#### Cách bật: + +```jsx +import React from 'react'; +import ReactDOM from 'react-dom/client'; +import App from './App'; + +const root = ReactDOM.createRoot(document.getElementById('root')); +root.render( + + + +); +``` + +#### Những gì Strict Mode làm: + +- Gọi render hai lần (chỉ trong development) để phát hiện side effect không mong muốn. +- Cảnh báo về deprecated lifecycle method. +- Cảnh báo về legacy string ref API. +- Phát hiện unexpected side effect. + +
+ +
+49. Controlled Component là gì? + +#### React + +**Controlled Component** là form element (input, textarea, select) có giá trị được kiểm soát bởi React state. Nguồn sự thật duy nhất là React state. + +#### Ví dụ: + +```jsx +import React, { useState } from 'react'; + +function ControlledForm() { + const [name, setName] = useState(''); + const [email, setEmail] = useState(''); + + const handleSubmit = e => { + e.preventDefault(); + console.log({ name, email }); + }; + + return ( +
+ setName(e.target.value)} + placeholder="Name" + /> + setEmail(e.target.value)} + placeholder="Email" + /> + +
+ ); +} +``` + +#### Ưu điểm: + +- Dễ validate đầu vào. +- Dễ đồng bộ hóa dữ liệu form. +- Có thể kiểm soát khi nào cho phép submit. + +
+ +
+50. Uncontrolled Component là gì? + +#### React + +**Uncontrolled Component** là form element quản lý state nội bộ của chính nó. Bạn dùng `ref` để truy cập giá trị khi cần, thay vì theo dõi từng thay đổi. + +#### Ví dụ: + +```jsx +import React, { useRef } from 'react'; + +function UncontrolledForm() { + const nameRef = useRef(); + const emailRef = useRef(); + + const handleSubmit = e => { + e.preventDefault(); + console.log({ + name: nameRef.current.value, + email: emailRef.current.value, + }); + }; + + return ( +
+ + + +
+ ); +} +``` + +#### So sánh Controlled vs. Uncontrolled: + +| | Controlled | Uncontrolled | +|---|---|---| +| **Nguồn sự thật** | React state | DOM | +| **Truy cập giá trị** | Qua state | Qua ref | +| **Validation** | Dễ | Khó hơn | +| **Cách dùng** | Form phức tạp | Form đơn giản | + +
+ +
+51. React Router là gì? + +#### React + +**React Router** là thư viện routing tiêu chuẩn cho React, cho phép xây dựng Single Page Application (SPA) với điều hướng phía client mà không reload trang. + +#### Cài đặt: + +```bash +npm install react-router-dom +``` + +#### Ví dụ cơ bản (v6): + +```jsx +import { BrowserRouter, Routes, Route, Link } from 'react-router-dom'; + +function App() { + return ( + + + + + } /> + } /> + } /> + } /> + + + ); +} +``` + +#### Các hook phổ biến: + +- `useNavigate()` — Điều hướng programmatically. +- `useParams()` — Truy cập URL parameters. +- `useLocation()` — Truy cập location object. +- `useSearchParams()` — Đọc/ghi query string. + +
+ +
+52. Sự khác biệt giữa React Router và routing thông thường là gì? + +#### React + +#### Sự khác biệt giữa React Router và routing thông thường: + +| Tiêu chí | React Router | Routing thông thường (Server-Side Routing) | +| -------------------- | ------------------------------------------------ | ------------------------------------------------ | +| **Loại routing** | Phía client (SPA) | Phía server (MPA) | +| **Chuyển trang** | Không reload trang (JS cập nhật URL) | Reload trang mỗi lần điều hướng | +| **Tốc độ** | Nhanh hơn vì không yêu cầu server | Chậm hơn do HTTP request mới | +| **SEO** | Kém hơn nếu không có SSR (Next.js giải quyết) | Tốt hơn vì nội dung được tải từ server | +| **Xử lý dữ liệu** | Render component động | Tải HTML từ server | +| **Cài đặt** | Cần React Router | Dùng khả năng server tiêu chuẩn | + +
+ +
+53. Các cách style React component là gì? + +#### React + +#### Các cách dùng style trong React component: + +1. **Inline style:** Style được truyền trực tiếp dưới dạng object qua thuộc tính `style`. + +```jsx +function InlineStyle() { + const style = { color: 'blue', fontSize: '20px' }; + return

Hello, React!

; +} +``` + +2. **CSS file:** Dùng file CSS thông thường import vào component. + +```jsx +import './styles.css'; +function CSSFile() { + return

Hello, React!

; +} +``` + +3. **CSS Modules:** Tạo style cục bộ cho mỗi component. + +```jsx +import styles from './styles.module.css'; +function CSSModule() { + return

Hello, React!

; +} +``` + +4. **Styled Components:** Dùng thư viện `styled-components`. + +```jsx +import styled from 'styled-components'; +const Heading = styled.h1`color: blue; font-size: 20px;`; +``` + +5. **Tailwind CSS:** Framework utility class. + +```jsx +function TailwindExample() { + return

Hello, React!

; +} +``` + +6. **Sass/SCSS:** CSS mở rộng với biến, mixin và nesting. + +```jsx +import './styles.scss'; +``` + +
+ +
+54. Ưu điểm của CSS Modules là gì? + +#### React + +**Ưu điểm của CSS Modules:** + +1. **Phạm vi cục bộ:** Style chỉ áp dụng cho component, không toàn cục. Ngăn xung đột class và đảm bảo style không ảnh hưởng đến các phần khác của ứng dụng. + +2. **Tên class duy nhất:** CSS Modules tự động tạo tên class duy nhất, loại bỏ rủi ro xung đột style với component khác. + +3. **Bảo trì dễ hơn:** Ít vấn đề hơn khi mở rộng dự án vì mỗi component có style riêng. + +4. **Isolation:** Mỗi component có style isolation hoàn toàn, đơn giản hóa refactoring và thay đổi style mà không ảnh hưởng component khác. + +5. **Tích hợp dễ với JavaScript:** Bạn có thể dùng style động qua JavaScript bằng cách thay đổi class tùy thuộc vào trạng thái component. + +
+ +
+55. Các cách tiếp cận tối ưu hiệu suất ứng dụng React là gì? + +#### React + +#### Các cách tối ưu hiệu suất React: + +1. **Memoize component:** `React.memo` cho functional component, `PureComponent` cho class component. + +2. **Memoize giá trị và hàm:** `useMemo` cho tính toán, `useCallback` cho hàm truyền xuống component con. + +3. **Tối ưu render danh sách:** Luôn dùng key duy nhất. Tránh render không cần thiết. + +4. **Lazy loading component:** `React.lazy` + `Suspense` để tải component theo yêu cầu. + +5. **Kiểm soát re-render:** `shouldComponentUpdate` hoặc `React.memo` để giảm render không cần thiết. + +6. **Code splitting:** `React.lazy` và dynamic import để load code chỉ khi cần. + +7. **Quản lý state:** Tránh lưu state toàn cục cho component không cần. Dùng Redux, Zustand cho state nặng. + +8. **Virtualization danh sách:** `react-window` hoặc `react-virtualized` để chỉ render mục hiển thị. + +9. **Tối ưu hình ảnh:** Dùng lazy loading cho ảnh. Nén và tối ưu ảnh. + +10. **Build production:** Đảm bảo build ở production mode (`npm run build`). + +
+ +
+56. Sự khác biệt giữa `memo` và `useMemo` là gì? + +#### React + +#### Sự khác biệt giữa `memo` và `useMemo` + +| Tiêu chí | memo | useMemo | +| ----------------------- | ------------------------------------------------------------ | ------------------------------------------------------ | +| **Là gì?** | Higher-order function (HOC) | Hook | +| **Mục đích** | Ngăn render lại component nếu props không thay đổi | Cache kết quả tính toán giữa các lần render | +| **Dùng ở đâu?** | Bọc component | Bên trong component | +| **Ví dụ** | `export default memo(MyComponent);` | `const value = useMemo(() => compute(), [deps]);` | +| **Cache gì?** | Toàn bộ component | Kết quả hàm | +| **Khi nào dùng?** | Component nhận cùng props không cần render lại | Tính toán tốn kém phụ thuộc vào biến | + +#### Khi nào dùng? + +- `memo` khi component nhận cùng props và không cần render lại. + +- `useMemo` khi cần lưu kết quả tính toán để không tính lại mỗi lần. + +
+ +
+57. Tại sao cần truyền hàm cho `setState()`? + +#### React + +Truyền hàm cho `setState()` cần thiết khi trạng thái mới phụ thuộc vào trạng thái trước đó. Điều này đảm bảo cập nhật đúng vì `setState()` hoạt động bất đồng bộ và có thể gộp các lần gọi. + +#### Ví dụ có vấn đề: + +```jsx +function Counter() { + const [count, setCount] = useState(0); + + function increment() { + setCount(count + 1); + setCount(count + 1); + } + + return ; +} +``` + +Ở đây, `count + 1` được tính hai lần từ cùng `count` cũ, nên nút chỉ tăng giá trị lên 1 thay vì 2. + +#### Cách đúng: + +```jsx +function Counter() { + const [count, setCount] = useState(0); + + function increment() { + setCount(prevCount => prevCount + 1); + setCount(prevCount => prevCount + 1); + } + + return ; +} +``` + +Ở đây, `setCount()` nhận giá trị `prevCount` hiện tại, nên increment hoạt động đúng và tăng giá trị lên 2. + +
+ +
+58. Làm thế nào để áp dụng validation props trong React? + +#### React + +**PropTypes** được dùng để validation props trong React. + +1. **Cài đặt PropTypes (nếu chưa cài)** + +```sh +npm install prop-types +``` + +2. **Dùng PropTypes trong functional component:** + +```jsx +import React from 'react'; +import PropTypes from 'prop-types'; + +function UserCard({ name, age, isAdmin }) { + return ( +
+

{name}

+

Age: {age}

+ {isAdmin &&

Admin Access

} +
+ ); +} + +// Định nghĩa PropTypes +UserCard.propTypes = { + name: PropTypes.string.isRequired, + age: PropTypes.number, + isAdmin: PropTypes.bool, +}; + +// Giá trị mặc định +UserCard.defaultProps = { + age: 18, + isAdmin: false, +}; + +export default UserCard; +``` + +#### Các PropTypes khả dụng: + +- `PropTypes.string` +- `PropTypes.number` +- `PropTypes.bool` +- `PropTypes.array` +- `PropTypes.object` +- `PropTypes.func` +- `PropTypes.node` (JSX hoặc text) +- `PropTypes.element` (React element) +- `PropTypes.oneOf(['value1', 'value2'])` (danh sách giá trị cho phép) +- `PropTypes.shape({ key: PropTypes.type })` (object với cấu trúc định nghĩa) + +#### Tóm tắt: + +PropTypes giúp tránh lỗi bằng cách kiểm tra kiểu prop, nhưng trong TypeScript điều này được thực hiện ở cấp ngôn ngữ. + +
+ +
+59. Các phương pháp tối ưu hiệu suất React là gì? + +#### React + +#### Kỹ thuật tối ưu hiệu suất React: + +1. **Memoize component:** `React.memo()`, `useMemo()`, `useCallback()`. + +2. **Tối ưu re-render:** Tránh state và props không cần thiết. `shouldComponentUpdate` và `React.PureComponent` cho class component. + +3. **Virtualization danh sách:** `react-window` hoặc `react-virtualized`. + +4. **Caching và debouncing:** `useMemo()` và `useCallback()` cho tính toán nặng. `lodash.debounce` hoặc `lodash.throttle` cho đầu vào người dùng. + +5. **Lazy loading:** `React.lazy()` + `Suspense`. Dynamic import. + +6. **Tránh side effect không cần thiết trong `useEffect`:** Truyền dependency đúng. Dùng `useRef` để lưu giá trị không render lại. + +7. **Tối ưu hình ảnh:** `next/image` trong Next.js. Tối ưu kích thước và format. + +8. **Tách state:** Dùng local state khi không cần global. Redux, Zustand hoặc Recoil cho thay đổi toàn cục. + +9. **Web Workers:** Cho tính toán nặng để không block main thread. + +
+ +
+60. Có thể dùng `async/await` trong React không? + +#### React + +Có, `async/await` có thể dùng trong React, nhưng có một số điểm cần lưu ý: + +1. **Dùng trong component:** `async/await` không thể dùng trực tiếp trong body component ở vị trí render logic hoặc trong phương thức như `render()`. Tuy nhiên, bạn có thể dùng trong event handler hoặc bên trong hook như `useEffect`. + +2. **Công cụ cho async request:** + +- Dùng `async/await` bên trong hàm được gọi từ hook: + +```jsx +useEffect(() => { + const fetchData = async () => { + const response = await fetch('https://api.example.com'); + const data = await response.json(); + setData(data); + }; + fetchData(); +}, []); +``` + +3. **Xử lý lỗi:** Đừng quên dùng `try/catch` để xử lý lỗi trong async request: + +```jsx +const fetchData = async () => { + try { + const response = await fetch('https://api.example.com'); + const data = await response.json(); + setData(data); + } catch (error) { + console.error('Error fetching data:', error); + } +}; +``` + +Vì vậy, `async/await` có thể và nên dùng cho các thao tác bất đồng bộ trong React, nhưng phải được tổ chức đúng trong component. + +
+ +
+61. Lịch sử phát triển của React là gì? + +#### React + +#### Lịch sử phát triển ngắn gọn của React: + +1. **2011** — React được tạo ra tại Facebook cho nhu cầu nội bộ bởi kỹ sư Jordan Walke để giải quyết vấn đề cập nhật giao diện hiệu quả. + +2. **2013** — Facebook phát hành React dưới dạng open-source. Ban đầu cộng đồng hoài nghi vì JSX có vẻ bất thường. + +3. **2015** — React 0.14 được phát hành: React và ReactDOM được tách ra, làm thư viện modular hơn. React Native được giới thiệu. + +4. **2016** — React 15 với cải tiến hiệu suất qua rendering engine mới. + +5. **2017** — React 16 (Fiber): kiến trúc mới cải thiện hiệu suất và hỗ trợ async rendering. Thêm portal và Error Boundary. + +6. **2018** — Facebook giới thiệu React Hooks, cho phép dùng state và lifecycle trong functional component. + +7. **2019** — React 16.8 với hỗ trợ hook chính thức. Concurrent Mode cải tiến experimental. + +8. **2020** — React 17: đơn giản hóa nâng cấp React dần dần trong dự án lớn. + +9. **2022** — React 18: Concurrent Rendering và các API mới `useTransition`, `useDeferredValue`. + +10. **2024** — React 19: SSR cải tiến, `use` function, React Compiler. + +#### Thay đổi chính qua thời gian: + +- Từ class component sang functional component với hook. +- Hỗ trợ server-side rendering (SSR). +- Concurrent Mode cho cập nhật giao diện mượt mà hơn. +- Tích hợp React với phát triển mobile qua React Native. + +
+ +
+62. React 19 có những tính năng mới gì? + +#### React + +React 19 giới thiệu nhiều cập nhật quan trọng nhằm cải thiện hiệu suất và trải nghiệm developer: + +1. **Hệ thống rendering mới:** Async rendering cho phép React quản lý cập nhật giao diện hiệu quả hơn. + +2. **React Compiler:** Compiler mới tự động tối ưu re-render, giảm cập nhật không cần thiết. + +3. **Actions API:** Cách tiếp cận mới để quản lý state và data mutation phía server. + +4. **Cơ chế Suspense cải tiến:** Kiểm soát tốt hơn việc tải dữ liệu bất đồng bộ. + +5. **Hook `use`:** Hook mới đơn giản hóa làm việc với async data và cải thiện hỗ trợ server component. + +6. **Hỗ trợ native cho meta tag:** `meta`, `title`, `link` và các thẻ khác được hỗ trợ mà không cần thư viện thêm. + +
+ +
+63. React developer khuyến nghị dùng gì sau khi Create React App bị deprecated? + +#### React + +Sau khi Create React App kết thúc hỗ trợ vào tháng 2 năm 2025, developer được khuyến nghị dùng các framework hiện đại: + +#### Framework được khuyến nghị: + +1. **Next.js:** SSR, SSG và tối ưu SEO. + +2. **React Router:** Xây dựng SPA với dynamic routing. + +3. **Expo:** Phát triển React Native đơn giản hóa cho ứng dụng mobile đa nền tảng. + +
+ +
+64. Hook `useDeferredValue` hoạt động như thế nào trong React? + +#### React + +`useDeferredValue` là React hook xuất hiện trong React 18 như một phần của tính năng Concurrent. Nó cho phép trì hoãn cập nhật của các giá trị nhất định, giảm độ ưu tiên của chúng và cho React cơ hội cập nhật giao diện với công việc quan trọng hơn trước. + +Điều này rất hữu ích khi giá trị thay đổi thường xuyên và cập nhật giao diện ở mỗi lần thay đổi tốn nhiều tài nguyên. + +##### `useDeferredValue` dùng để làm gì? + +- Tránh delay và lag trong ứng dụng phức tạp quan trọng đến UI responsiveness. +- Cải thiện tương tác người dùng, đặc biệt khi nhiều dữ liệu thay đổi (tìm kiếm, lọc, render danh sách lớn). +- Đảm bảo animation và chuyển đổi giữa các state mượt mà. + +##### Cách hoạt động? + +```jsx +const deferredValue = useDeferredValue(value); +``` + +- React ngay lập tức cập nhật các thay đổi quan trọng (ưu tiên cao). +- Giá trị deferred (`deferredValue`) được cập nhật bất đồng bộ sau khi React xử lý xong các tác vụ khẩn hơn. + +##### Ví dụ: + +###### Không có `useDeferredValue`: + +```jsx +import { useState, useMemo } from 'react'; + +function SearchList({ items }) { + const [query, setQuery] = useState(''); + + const filteredItems = useMemo(() => { + return items.filter(item => item.includes(query)); + }, [items, query]); + + return ( + <> + setQuery(e.target.value)} placeholder="Search..." /> + + + ); +} +``` + +###### Với `useDeferredValue`: + +```jsx +import { useState, useDeferredValue, useMemo } from 'react'; + +function SearchList({ items }) { + const [query, setQuery] = useState(''); + const deferredQuery = useDeferredValue(query); + + const filteredItems = useMemo(() => { + return items.filter(item => item.includes(deferredQuery)); + }, [items, deferredQuery]); + + return ( + <> + setQuery(e.target.value)} placeholder="Search..." /> + + + ); +} +``` + +Trong phiên bản này, đầu vào người dùng vẫn tức thì và mượt mà trong khi lọc danh sách thực hiện bất đồng bộ. + +##### Khi nào dùng `useDeferredValue` tốt nhất? + +- Danh sách với nhiều mục. +- Form với lọc tích cực và autocomplete. +- Bất kỳ trường hợp nào cập nhật giao diện thường xuyên có thể tạo trải nghiệm người dùng không tốt. + +
+ +
+65. Refs được dùng như thế nào trong React để tương tác với DOM element? + +#### React + +Refs trong React được dùng để truy cập trực tiếp DOM element hoặc component, bỏ qua cơ chế props và state tiêu chuẩn. + +1. **Tạo ref:** Dùng `React.createRef()` để tạo ref. + +```jsx +const myRef = React.createRef(); +``` + +2. **Gắn ref vào element:** Ref được truyền vào DOM element qua thuộc tính `ref`. + +```jsx + +``` + +3. **Tương tác với DOM:** Ref cung cấp quyền truy cập DOM element qua `.current`. Ví dụ, để set focus: + +```jsx +myRef.current.focus(); +``` + +4. **Giới hạn:** Refs không nên dùng để quản lý state. Chúng chỉ dùng cho tương tác DOM khi cần thiết (ví dụ: focus, chọn text, hoặc animation). + +5. **Functional component:** Trong React 16.8 trở lên, `useRef` được dùng cho functional component. + +```jsx +const inputRef = useRef(); +inputRef.current.focus(); +``` + +
+ +
+66. Làm thế nào để dùng InnerHTML trong React? + +#### React + +Trong React, thuộc tính `dangerouslySetInnerHTML` được dùng để chèn nội dung HTML vào DOM. Cách này cho phép chèn HTML trực tiếp vào component, nhưng có thể nguy hiểm vì được gọi là "nguy hiểm" — nó cho phép nhúng HTML thô, có thể dẫn đến tấn công XSS nếu dữ liệu không được làm sạch. + +#### Ví dụ dùng `dangerouslySetInnerHTML`: + +```jsx +const MyComponent = () => { + const htmlContent = '

This is HTML content.

'; + + return
; +}; +``` + +#### Khi nào dùng: + +- Nếu bạn chắc chắn dữ liệu an toàn (ví dụ: từ server của chính bạn). +- Khi cần nhúng nội dung HTML động, như bài viết có markup HTML. + +**Cảnh báo bảo mật:** Không bao giờ dùng `dangerouslySetInnerHTML` để chèn dữ liệu nhận từ người dùng hoặc nguồn ngoài mà không làm sạch trước. Dùng thư viện như DOMPurify để tránh tấn công XSS. + +```jsx +import DOMPurify from 'dompurify'; + +const MyComponent = () => { + const dirtyHtml = ""; + const cleanHtml = DOMPurify.sanitize(dirtyHtml); + + return
; +}; +``` + +
+ +
+67. ReactDOMServer là gì? + +#### React + +**`ReactDOMServer`** là thư viện đi kèm với React được dùng để render React component trên server, tức là cho server-side rendering (SSR). Nó cho phép tạo HTML trên server và gửi đến client, giúp cải thiện hiệu suất và SEO. + +#### Các phương thức chính: + +1. **`ReactDOMServer.renderToString()`:** Render React element thành chuỗi HTML. Đây là phương thức chính để tạo HTML tĩnh cho lần tải trang đầu tiên. + +```jsx +import ReactDOMServer from 'react-dom/server'; +const html = ReactDOMServer.renderToString(); +``` + +2. **`ReactDOMServer.renderToStaticMarkup()`:** Render HTML không có các thuộc tính React thêm vào như `data-reactroot`. Phù hợp để tạo trang hoàn toàn tĩnh. + +```jsx +const html = ReactDOMServer.renderToStaticMarkup(); +``` + +3. **`ReactDOMServer.hydrate()`:** Dùng ở phía client để "hydrate" HTML được render từ server, tức là gắn tính tương tác React vào HTML sẵn có. + +```jsx +ReactDOM.hydrate(, document.getElementById('root')); +``` + +`ReactDOMServer` cho phép tạo trang được pre-render, cải thiện tốc độ tải và hữu ích cho SEO. + +
+ +
+68. Package `react-dom` được dùng để làm gì? + +#### React + +Package `react-dom` được dùng để tương tác giữa React và DOM thực trong ứng dụng web. Các chức năng chính: + +1. **`ReactDOM.render()`:** Render component vào DOM thực. Đây là phương thức chính kết nối React với HTML element. + +```jsx +ReactDOM.render(, document.getElementById('root')); +``` + +2. **`ReactDOM.hydrate()`:** Dùng để hydrate HTML được render từ server (ví dụ: SSR). + +```jsx +ReactDOM.hydrate(, document.getElementById('root')); +``` + +3. **`ReactDOM.createPortal()`:** Cho phép render element con ở nơi khác trong DOM, bên ngoài phân cấp component thông thường. + +```jsx +ReactDOM.createPortal(, document.getElementById('modal-root')); +``` + +4. **`ReactDOM.unmountComponentAtNode()`:** Xóa React component khỏi DOM. + +```jsx +ReactDOM.unmountComponentAtNode(document.getElementById('root')); +``` + +5. **`ReactDOM.findDOMNode()`:** Cung cấp quyền truy cập DOM element thực của component (ít dùng vì có cách hiện đại hơn qua refs). + +
+ +
+69. Làm thế nào để dùng `React.lazy` và `React.Suspense` cho code splitting? + +#### React + +`React.lazy` và `React.Suspense` được dùng để **tải component động** trong React, cho phép **code splitting**. Điều này có nghĩa là các phần code chỉ được tải khi cần, cải thiện hiệu suất ứng dụng. + +#### Cách hoạt động: + +1. **`React.lazy()`** cho phép tải component lazily. + +2. **`React.Suspense`** bọc phần code chưa tải và hiển thị fallback content (ví dụ: loader) trong khi component đang tải. + +#### Ví dụ: + +```jsx +// Component được tải động +const MyComponent = React.lazy(() => import('./MyComponent')); + +function App() { + return ( +
+

Ứng dụng của tôi

+ Đang tải...
}> + + + + ); +} +``` + +#### Ưu điểm: + +- Cải thiện hiệu suất bằng cách tải component chỉ khi cần. +- Giảm kích thước bundle ban đầu vì các phần ứng dụng được tải theo yêu cầu. + +
+ +
+70. Các best practice bảo mật trong React là gì? + +#### React + +#### Best practice bảo mật trong React: + +1. **Ngăn XSS (Cross-Site Scripting):** + - Luôn làm sạch dữ liệu từ người dùng trước khi hiển thị trong component. + - Dùng JSX (React escape input tự động, nhưng tránh dùng `dangerouslySetInnerHTML` khi có thể). + +2. **Tránh code injection:** + - Không truyền dữ liệu chưa validated vào `eval()`, `setTimeout()`, `setInterval()`. + +3. **Truy cập API an toàn:** + - Dùng HTTPS để bảo vệ dữ liệu truyền qua mạng. + - Dùng authentication, authorization và cookie bảo mật (`HttpOnly`, `Secure`). + +4. **Bảo vệ chống CSRF:** + - Dùng CSRF token để validate tất cả request thay đổi dữ liệu trên server. + - Dùng flag `SameSite` cho cookie để giới hạn truy cập cùng domain. + +5. **Kiểm soát truy cập:** + - Kiểm tra quyền người dùng trước khi gửi request đến server. + - Không tin tưởng kiểm tra phía client. Tất cả kiểm tra server-side phải là cuối cùng. + +6. **Cập nhật dependency:** + - Thường xuyên kiểm tra và cập nhật dependency. Dùng `npm audit`. + +7. **Quản lý bí mật:** + - Không lưu trữ bí mật (API key, mật khẩu) trong code client-side. + +8. **Dùng Content Security Policy (CSP):** + - Dùng CSP để ngăn script không mong muốn thực thi trên site. + +9. **Bảo vệ chống Clickjacking:** + - Dùng header `X-Frame-Options` hoặc `Content-Security-Policy` để ngăn site bị nhúng trong `