Làm thế nào để comment trong React?
Làm thế nào để comment trong React?
Trong React, việc thêm comment vào mã JSX có thể hơi khác so với cách bạn thường thêm comment trong HTML hoặc JavaScript thuần túy. Điều này là do JSX là một cú pháp mở rộng cho JavaScript, được xử lý bởi Babel trước khi chuyển thành mã JavaScript mà trình duyệt có thể hiểu. Dưới đây là cách để thêm comment trong React:
Để thêm comment trong JSX, bạn sử dụng cú pháp của comment trong JavaScript nhưng phải đặt nó bên trong dấu ngoặc nhọn {} vì JSX là JavaScript. Điều này cho phép bạn chèn một biểu thức JavaScript - trong trường hợp này là một comment - vào trong JSX.
function MyComponent() {
return (
<div>
{/* Đây là comment trong JSX */}
<h1>Hello, World!</h1>
</div>
);
}
Nếu bạn muốn comment nhiều dòng trong JSX, bạn vẫn sử dụng cùng một cú pháp nhưng mở rộng nó ra nhiều dòng.
function MyComponent() {
return (
<div>
{/*
Đây là comment nhiều dòng
trong JSX.
*/}
<h1>Hello, World!</h1>
</div>
);
}
Nếu bạn đang viết comment bên ngoài phần trả về của JSX, bạn có thể sử dụng comment JavaScript thông thường mà không cần dấu ngoặc nhọn.
// Đây là comment bên ngoài JSX
function MyComponent() {
return (
<div>
<h1>Hello, World!</h1>
</div>
);
}
{}.Việc sử dụng comment một cách hiệu quả có thể giúp làm cho mã nguồn của bạn dễ đọc và bảo trì hơn.
ReactJS là gì? Nêu các tính năng nổi bật của Reactjs?
ReactJS, thường được gọi đơn giản là React, là một thư viện JavaScript mã nguồn mở được phát triển bởi Facebook (nay là Meta) để xây dựng giao diện người dùng (UI) động và hiệu quả cho các ứng dụng web và di động. React được giới thiệu vào năm 2013 và nhanh chóng trở thành một trong những công nghệ phát triển giao diện phổ biến nhất, được sử dụng bởi nhiều công ty lớn và dự án trên toàn thế giới.
ReactJS sử dụng kiến trúc dựa trên component, nghĩa là giao diện người dùng được chia thành các phần nhỏ, độc lập gọi là components. Mỗi component có thể quản lý trạng thái (state) của nó và được tái sử dụng trong ứng dụng, giúp việc phát triển ứng dụng trở nên dễ dàng và hiệu quả hơn.
React sử dụng Virtual DOM để tối ưu hóa hiệu suất bằng cách giảm thiểu số lượng cập nhật DOM thực tế. Khi trạng thái của một component thay đổi, React sẽ tạo ra một Virtual DOM tree mới và so sánh nó với phiên bản trước đó để xác định những thay đổi cần được thực hiện trên DOM thực tế. Điều này giúp tăng tốc độ và hiệu suất của ứng dụng.
React thực hiện một chiều dữ liệu ràng buộc (one-way data binding), nghĩa là dữ liệu trong ứng dụng chỉ di chuyển theo một hướng từ parent components xuống child components thông qua props. Điều này giúp kiểm soát và theo dõi dòng dữ liệu trong ứng dụng dễ dàng hơn, giảm thiểu lỗi và tăng khả năng bảo trì.
JSX là một cú pháp mở rộng cho JavaScript cho phép viết XML/HTML trong mã JavaScript. Sử dụng JSX giúp mã nguồn dễ đọc và viết hơn, đồng thời cho phép React hiển thị thông tin từ mã JavaScript dễ dàng hơn thông qua cú pháp giống như template.
React Native là một framework được xây dựng dựa trên React, cho phép phát triển ứng dụng di động chéo nền tảng (cross-platform) với hiệu suất gần như ứng dụng native. React Native sử dụng cùng một kiến trúc component và cho phép chia sẻ code giữa ứng dụng web và di động, giúp tối ưu hóa quá trình phát triển.
React có một cộng đồng lớn và đang phát triển mạnh mẽ với hàng nghìn nhà phát triển và công ty đóng góp. Điều này đảm bảo rằng React sẽ tiếp tục được cải thiện và hỗ trợ trong tương lai, cũng như có sẵn một lượng lớn tài nguyên học tập và thư viện bên thứ ba.
ReactJS đã trở thành một công cụ không thể thiếu trong bộ công cụ của các nhà phát triển front-end, nhờ vào sự linh hoạt, hiệu suất cao và cộng đồng hỗ trợ mạnh mẽ.
useState() trong React là gì?
useState() là một Hook trong React cho phép bạn thêm trạng thái (state) React vào trong functional components. Trước khi Hooks được giới thiệu trong React 16.8, trạng thái chỉ có thể được sử dụng trong class components. useState() cung cấp một cách để lưu trữ và quản lý dữ liệu địa phương trong một component mà không cần chuyển đổi nó thành một class component.
useState()useState() nhận một giá trị khởi tạo và trả về một mảng với hai phần tử: giá trị hiện tại của trạng thái và một hàm để cập nhật trạng thái đó. Bạn có thể sử dụng giá trị này trong component của mình và gọi hàm cập nhật khi bạn muốn thay đổi trạng thái.
Ví dụ:
import React, { useState } from 'react';
function Counter() {
// Khai báo một biến trạng thái mới, gọi là "count"
const [count, setCount] = useState(0);
return (
<div>
<p>Bạn đã click {count} lần</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
Trong ví dụ trên, useState(0) khởi tạo trạng thái với giá trị ban đầu là 0. Biến count được sử dụng để hiển thị giá trị hiện tại của trạng thái, và hàm setCount được sử dụng để cập nhật giá trị của count.
useState()setCount trong ví dụ trên) không tự động gộp hoặc kết hợp các cập nhật. Để cập nhật trạng thái dựa trên giá trị hiện tại, bạn nên sử dụng một hàm nhận giá trị hiện tại của trạng thái và trả về giá trị mới.useState() không tự động gộp các cập nhật trạng thái như this.setState trong class components. Mỗi lần gọi useState() tạo ra một trạng thái và hàm cập nhật riêng biệt cho trạng thái đó.useState() trong một component để quản lý nhiều biến trạng thái.useState() là một phần cơ bản của việc sử dụng Hooks trong React, giúp việc quản lý trạng thái trong functional components trở nên dễ dàng và linh hoạt hơn.
DOM ảo là gì?
DOM ảo (Virtual DOM) là một khái niệm quan trọng trong phát triển ứng dụng web hiện đại, đặc biệt là trong các thư viện và framework như React. Virtual DOM là một bản sao nhẹ của DOM thực tế (Real DOM) và được sử dụng như một lớp trung gian giữa trạng thái của ứng dụng và trạng thái được hiển thị trên giao diện người dùng.
Virtual DOM là một kỹ thuật hiệu quả giúp tối ưu hóa việc cập nhật giao diện người dùng trong các ứng dụng web phức tạp. Bằng cách giảm thiểu số lượng tương tác trực tiếp với Real DOM, Virtual DOM giúp cải thiện đáng kể hiệu suất và trải nghiệm người dùng, đồng thời cung cấp một mô hình phát triển ứng dụng linh hoạt và hiệu quả.
React hook là gì?
React Hook là một tính năng được giới thiệu trong React 16.8, cho phép bạn sử dụng state và các tính năng React khác mà không cần phải viết một class. Hooks là các hàm cho phép bạn "kết nối" vào các tính năng lifecycle và state của React từ các function components. Trước khi có Hooks, các function components được coi là stateless components và không thể sử dụng các tính năng như state hay lifecycle methods. Hooks đã thay đổi điều này, mang lại khả năng sử dụng rộng rãi hơn cho function components và giúp viết ứng dụng React trở nên dễ dàng và gọn gàng hơn.
useState: Cho phép bạn thêm state vào function components.
const [count, setCount] = useState(0);
useEffect: Cho phép bạn thực hiện các side effect trong function components. Nó tương tự như componentDidMount, componentDidUpdate, và componentWillUnmount trong class components.
useEffect(() => {
document.title = `You clicked ${count} times`;
});
useContext: Cho phép bạn truy cập vào context và dữ liệu từ context provider mà không cần sử dụng consumer.
const value = useContext(MyContext);
React Hooks mang lại một cách tiếp cận mới và mạnh mẽ để xây dựng các components trong React, giúp việc quản lý state và lifecycle trở nên dễ dàng và linh hoạt hơn. Bằng cách sử dụng Hooks, các nhà phát triển có thể viết code gọn gàng và dễ bảo trì hơn, đồng thời tận dụng được sức mạnh của React mà không cần phải dựa vào class components.
State trong React là gì?
State trong Reactjs là một đối tượng JavaScript được sử dụng để lưu trữ thông tin về trạng thái của một component. State có thể thay đổi theo thời gian, thường do sự kiện người dùng hoặc hệ thống, và mỗi khi state thay đổi, React sẽ tự động thực hiện việc re-render component để cập nhật giao diện người dùng phản ánh trạng thái mới.
setState() trong class components hoặc hook useState() trong function components. React sẽ lên lịch một cập nhật cho component khi state thay đổi.Trong class component:
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = { count: 0 };
}
incrementCount = () => {
this.setState({ count: this.state.count + 1 });
};
render() {
return (
<div>
<p>Count: {this.state.count}</p>
<button onClick={this.incrementCount}>Increment</button>
</div>
);
}
}
Trong function component với hook useState:
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
const incrementCount = () => {
setCount(count + 1);
};
return (
<div>
<p>Count: {count}</p>
<button onClick={incrementCount}>Increment</button>
</div>
);
}
Trong cả hai ví dụ trên, count là một phần của state của component Counter. Khi nút "Increment" được nhấn, hàm incrementCount được gọi, cập nhật state, và gây ra việc re-render component với giá trị count mới.
Tóm lại, state là một phần cốt lõi của React giúp tạo ra các ứng dụng động và tương tác, cho phép các component phản ứng với dữ liệu đầu vào và thay đổi theo thời gian.
React Hooks là gì?
React Hooks là một tính năng được giới thiệu trong React 16.8, cho phép bạn sử dụng state và các tính năng React khác mà không cần phải viết một class. Hooks là các hàm cho phép bạn "kết nối" vào các tính năng lifecycle và state của React từ các function components. Trước khi có Hooks, các function components được coi là stateless components và không thể sử dụng các tính năng như state hay lifecycle methods. Hooks đã thay đổi điều này, mang lại khả năng sử dụng rộng rãi hơn cho function components và giúp viết ứng dụng React trở nên dễ dàng và gọn gàng hơn.
useState: Cho phép bạn thêm state vào function components.
const [count, setCount] = useState(0);
useEffect: Cho phép bạn thực hiện các side effect trong function components. Nó tương tự như componentDidMount, componentDidUpdate, và componentWillUnmount trong class components.
useEffect(() => {
document.title = `You clicked ${count} times`;
});
useContext: Cho phép bạn truy cập vào context và dữ liệu từ context provider mà không cần sử dụng consumer.
const value = useContext(MyContext);
Tóm lại, React Hooks mang lại một cách tiếp cận mới và mạnh mẽ để xây dựng các components trong React, giúp việc quản lý state và lifecycle trở nên dễ dàng và linh hoạt hơn. Bằng cách sử dụng Hooks, các nhà phát triển có thể viết code gọn gàng và dễ bảo trì hơn, đồng thời tận dụng được sức mạnh của React mà không cần phải dựa vào class components.
JSX là gì? Trình duyệt có đọc được JSX không?
JSX là một cú pháp mở rộng của JavaScript được sử dụng trong React để mô tả cấu trúc giao diện người dùng. JSX cung cấp một cách để viết các thành phần UI giống như HTML trong mã JavaScript, giúp việc phát triển giao diện trở nên trực quan và dễ hiểu hơn. Mặc dù JSX trông giống HTML, nhưng thực chất nó là một cú pháp đặc biệt mà React sử dụng để tạo ra các đối tượng React Element.
JSX không?Các trình duyệt web không thể hiểu trực tiếp JSX vì nó không phải là một phần của tiêu chuẩn JavaScript. Để sử dụng JSX trong các ứng dụng web, mã JSX cần được "biên dịch" thành JavaScript thông thường mà trình duyệt có thể hiểu được. Quá trình biên dịch này thường được thực hiện bằng các công cụ như Babel, một trình biên dịch JavaScript hiện đại có thể chuyển đổi JSX thành các lệnh gọi hàm React.createElement() trước khi mã được chạy trong trình duyệt.
Ví dụ, đoạn mã JSX sau:
const element = <h1>Hello, world!</h1>;
sẽ được Babel biên dịch thành:
const element = React.createElement('h1', null, 'Hello, world!');
Sau khi biên dịch, mã JavaScript kết quả có thể được thực thi bởi trình duyệt mà không gặp vấn đề gì.
Sự khác nhau giữa state và props trong React là gì?
Trong React, state và props là hai khái niệm cốt lõi giúp quản lý dữ liệu và tương tác trong các component. Dưới đây là sự khác biệt chính giữa state và props:
state là một tập hợp các dữ liệu động mà component có thể sở hữu và quản lý. State có thể thay đổi theo thời gian, thường do sự kiện người dùng hoặc hệ thống.state được quản lý bên trong component và có thể được cập nhật bằng cách sử dụng this.setState() trong class components hoặc hooks như useState trong function components.state là riêng tư và chỉ có thể truy cập hoặc thay đổi bởi chính component đó.state khi dữ liệu cần thay đổi theo thời gian hoặc do tương tác người dùng.props (viết tắt của "properties") là các tham số mà component nhận từ bên ngoài, thường là từ component cha. Props được sử dụng để truyền dữ liệu và sự kiện giữa các component.props là bất biến, tức là một khi đã được truyền vào component, bạn không thể thay đổi giá trị của chúng bên trong component đó.props giúp tăng tính tái sử dụng của component bằng cách cho phép component nhận dữ liệu động từ cha, giúp tạo ra các component linh hoạt và tái sử dụng.props khi bạn muốn truyền dữ liệu từ component cha xuống component con hoặc khi bạn muốn render component dựa trên dữ liệu đầu vào từ bên ngoài.class ParentComponent extends React.Component {
state = {
greeting: 'Hello'
};
render() {
return <ChildComponent greeting={this.state.greeting} />;
}
}
class ChildComponent extends React.Component {
render() {
// Props được sử dụng ở đây và không thể thay đổi
return <h1>{this.props.greeting}, World!</h1>;
}
}
Trong ví dụ trên, ParentComponent có state chứa dữ liệu chào hỏi, và nó truyền state này như một prop cho ChildComponent. ChildComponent sau đó sử dụng prop để render dữ liệu, nhưng không thể thay đổi nó.
Tóm lại, state và props đều quan trọng trong việc xây dựng các ứng dụng React, nhưng chúng phục vụ cho các mục đích khác nhau: state cho phép component quản lý dữ liệu động của chính mình, trong khi props cho phép truyền dữ liệu giữa các component, tạo ra một dòng dữ liệu một chiều từ component cha xuống component con.
Props trong React là gì?
Props trong React là một cơ chế để truyền dữ liệu từ một component cha sang một component con trong ứng dụng React. Props (viết tắt của "properties") là các đối số mà bạn cung cấp cho một component React và chúng là read-only, tức là không thể được thay đổi bởi component nhận props.
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
function App() {
return <Welcome name="Alice" />;
}
Trong ví dụ trên, component Welcome nhận props và sử dụng nó để hiển thị tên. Component App truyền một prop name với giá trị "Alice" đến component Welcome.
Tóm lại, props là một phần quan trọng của React, giúp xây dựng các ứng dụng có cấu trúc tốt và dễ quản lý.
Component trong Reactjs là gì?
Trong React, một component là một đơn vị độc lập, có thể tái sử dụng, thường đại diện cho một phần của giao diện người dùng (UI). Mỗi component trong React được xây dựng để hoạt động độc lập, cho phép bạn tạo ra các ứng dụng phức tạp bằng cách kết hợp nhiều component nhỏ và tái sử dụng chúng.
Trong React, có hai loại component chính:
Class Components: Được xây dựng sử dụng ES6 class. Class components cho phép sử dụng các tính năng như state và lifecycle methods.
class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
Function Components: Được viết dưới dạng các hàm JavaScript. Với sự giới thiệu của Hooks trong React 16.8, function components cũng có thể sử dụng state và các tính năng khác giống như class components.
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
Components được sử dụng để xây dựng các phần tử UI bằng cách trả về một cây các React elements. Cây này được React sử dụng để xây dựng DOM và cập nhật UI khi dữ liệu thay đổi.
Components là trái tim của bất kỳ ứng dụng React nào, giúp tạo ra các ứng dụng web động và phản hồi nhanh chóng với khả năng tái sử dụng cao và dễ dàng bảo trì. Sự linh hoạt và mạnh mẽ của components làm cho React trở thành một trong những thư viện JavaScript phổ biến nhất cho phát triển giao diện người dùng.
ReactDOM là gì?
ReactDOM là một thư viện trong hệ sinh thái React, cung cấp các API cần thiết để gắn kết React components vào DOM (Document Object Model). Nói cách khác, ReactDOM cho phép bạn "mount" (gắn) các components React vào DOM, giúp chúng có thể hiển thị và tương tác với người dùng trong môi trường web.
ReactDOM.render(): Phương thức này được sử dụng để render một React element hoặc component vào một nút DOM cụ thể trong HTML. Đây là bước cần thiết để biến mã JSX hoặc components thành các phần tử HTML có thể nhìn thấy được trên trình duyệt.
ReactDOM.render(<App />, document.getElementById('root'));
Trong ví dụ trên, ReactDOM.render sẽ render component App vào nút DOM có id là root.
ReactDOM.createPortal(): Phương thức này cho phép bạn render children vào một nút DOM khác, không phải là nút DOM hiện tại của component. Điều này hữu ích trong các trường hợp như khi bạn muốn render một modal, tooltip, hoặc một toast notification vào một phần khác của DOM để tránh các vấn đề về CSS hoặc z-index.
ReactDOM.unmountComponentAtNode(): Phương thức này được sử dụng để gỡ bỏ một component đã được mount từ DOM. Điều này thường được sử dụng để dọn dẹp khi component không còn cần thiết nữa, giúp tránh rò rỉ bộ nhớ.
ReactDOM.findDOMNode(): Phương thức này (không được khuyến nghị sử dụng trong các phiên bản mới của React) được sử dụng để tìm nút DOM tương ứng với một instance component cụ thể. Tuy nhiên, việc sử dụng phương thức này thường không cần thiết và có thể được thay thế bằng cách sử dụng refs.
Trong các phiên bản mới của React, việc sử dụng ReactDOM đã được đơn giản hóa với sự xuất hiện của React 18 và các API mới như createRoot và hydrateRoot, cung cấp một cách tiếp cận hiệu quả hơn cho việc render và hydrate ứng dụng React.
Tóm lại, ReactDOM là một phần không thể thiếu trong việc sử dụng React để xây dựng ứng dụng web, nó cung cấp cầu nối giữa React components và DOM, cho phép các components có thể hiển thị và hoạt động trong môi trường web.
React context là gì?
React Context là một cơ chế trong React cho phép bạn chia sẻ dữ liệu một cách dễ dàng giữa tất cả các component trong cùng một cây component, mà không cần phải truyền props xuống từng cấp một cách thủ công. Context được thiết kế để chia sẻ dữ liệu mà có thể được coi là "toàn cục" cho một cây component, như là thông tin xác thực người dùng hiện tại, theme ứng dụng, hoặc ngôn ngữ ưu tiên.
Để sử dụng Context, bạn sẽ tạo một Context mới bằng cách sử dụng React.createContext() và sau đó sử dụng Provider để bao bọc cây component của bạn. Các component con sau đó có thể đăng ký để lắng nghe thay đổi của Context thông qua Consumer hoặc useContext hook.
import React, { createContext, useContext } from 'react';
// Tạo một Context mới
const UserContext = createContext();
function App() {
// Sử dụng Provider để truyền dữ liệu
return (
<UserContext.Provider value="Alice">
<Header />
</UserContext.Provider>
);
}
function Header() {
// Sử dụng useContext hook để truy cập dữ liệu từ Context
const user = useContext(UserContext);
return <h1>Welcome, {user}!</h1>;
}
Trong ví dụ trên, UserContext được tạo ra và sử dụng để truyền tên người dùng "Alice" xuống component Header mà không cần phải truyền qua props.
Tóm lại, React Context là một công cụ hữu ích cho việc quản lý trạng thái toàn cục và chia sẻ dữ liệu giữa các component mà không cần phải truyền props một cách thủ công qua cây component.
Ưu điểm của việc sử dụng React Hooks là gì?
React Hooks là một tính năng được giới thiệu trong React 16.8, cho phép bạn sử dụng state và các tính năng React khác mà không cần phải viết một class. Việc sử dụng React Hooks mang lại nhiều ưu điểm:
componentDidMount, componentDidUpdate, và componentWillUnmount, giảm lượng boilerplate code cần thiết.useState và useEffect là hai hooks cơ bản giúp bạn sử dụng state và side effects trong function components một cách dễ dàng.useContext cho phép bạn truy cập dữ liệu từ React Context mà không cần phải sử dụng Consumer component.useMemo và useCallback giúp tránh re-renders không cần thiết, tối ưu hiệu suất ứng dụng.Tóm lại, React Hooks mang lại nhiều lợi ích như việc viết component dễ dàng và gọn gàng hơn, tái sử dụng logic một cách dễ dàng, code dễ hiểu và dễ bảo trì, dễ dàng sử dụng các tính năng React, và giúp tối ưu hiệu suất ứng dụng.
Sự khác biệt giữa smart component và dumb component là gì?
Trong phát triển ứng dụng React, thuật ngữ "smart" component (còn được gọi là container component) và "dumb" component (còn được gọi là presentational component) thường được sử dụng để mô tả hai loại component khác nhau dựa trên vai trò và chức năng của chúng trong ứng dụng.
Sự phân chia giữa smart và dumb components giúp tạo ra một cấu trúc ứng dụng rõ ràng và dễ quản lý, nơi logic ứng dụng được tách biệt khỏi UI, làm cho mã nguồn dễ đọc, dễ bảo trì và dễ tái sử dụng hơn.
Làm cách nào bạn ngăn một component hiển thị trong React?
Để ngăn một component hiển thị trong React, bạn có thể sử dụng một số cách sau:
Bạn có thể sử dụng một biểu thức điều kiện trong JSX để quyết định xem một component có được render hay không. Điều này thường được thực hiện bằng cách sử dụng toán tử ba ngôi hoặc các cấu trúc điều kiện khác như &&.
Ví dụ sử dụng toán tử ba ngôi:
function MyComponent({ shouldShow }) {
return (
<div>
{shouldShow ? <ComponentToShow /> : null}
</div>
);
}
Ví dụ sử dụng &&:
function MyComponent({ shouldShow }) {
return (
<div>
{shouldShow && <ComponentToShow />}
</div>
);
}
Trong cả hai ví dụ trên, ComponentToShow chỉ được render nếu shouldShow là true.
null từ ComponentMột component trong React có thể ngăn chính nó hiển thị bằng cách trả về null từ phương thức render (trong class component) hoặc từ chính bản thân nó (trong functional component).
Ví dụ với functional component:
function MyComponent({ shouldShow }) {
if (!shouldShow) {
return null;
}
return (
<div>
{/* Nội dung của component */}
</div>
);
}
Ví dụ với class component:
class MyComponent extends React.Component {
render() {
if (!this.props.shouldShow) {
return null;
}
return (
<div>
{/* Nội dung của component */}
</div>
);
}
}
Trong cả hai trường hợp, component sẽ không render gì cả nếu shouldShow là false.
Bạn cũng có thể sử dụng một Higher-Order Component để kiểm soát việc hiển thị của một component. HOC là một hàm nhận vào một component và trả về một component mới với một số logic bổ sung - trong trường hợp này, logic để quyết định xem component gốc có được hiển thị hay không.
function withConditionalRendering(WrappedComponent) {
return function({ shouldShow, ...props }) {
if (!shouldShow) {
return null;
}
return <WrappedComponent {...props} />;
};
}
Sử dụng HOC:
const MyComponentWithConditionalRendering = withConditionalRendering(MyComponent);
// Trong JSX của bạn
<MyComponentWithConditionalRendering shouldShow={true} />
Sử dụng các phương pháp trên, bạn có thể dễ dàng kiểm soát việc hiển thị của các component trong ứng dụng React của mình.
Reselect là gì và nó hoạt động như thế nào?
Reselect là một thư viện selector cho Redux, giúp tạo ra các selector có thể được tái sử dụng và memoized. Selector là một hàm cho phép bạn trích xuất và chuyển đổi dữ liệu từ Redux store một cách hiệu quả. Reselect được sử dụng để tính toán dữ liệu phái sinh từ state của Redux store mà không cần phải viết lại logic tính toán mỗi khi state thay đổi.
Tạo Selector: Bạn tạo một selector bằng cách sử dụng hàm createSelector từ thư viện Reselect. Selector này sẽ nhận vào một hoặc nhiều "input selector" và một hàm "transform function" để tính toán và trả về dữ liệu mong muốn.
import { createSelector } from 'reselect';
const getVisibilityFilter = state => state.visibilityFilter;
const getTodos = state => state.todos;
const getVisibleTodos = createSelector(
[getVisibilityFilter, getTodos],
(visibilityFilter, todos) => {
switch (visibilityFilter) {
case 'SHOW_COMPLETED':
return todos.filter(t => t.completed);
case 'SHOW_ACTIVE':
return todos.filter(t => !t.completed);
default:
return todos;
}
}
);
Memoization: Khi selector được gọi, nó sẽ kiểm tra xem input đã thay đổi hay chưa. Nếu input không thay đổi, selector sẽ trả về kết quả từ bộ nhớ cache thay vì tính toán lại.
Sử dụng trong Component: Bạn có thể sử dụng selector trong component của mình để trích xuất và chuyển đổi dữ liệu từ store một cách hiệu quả.
import { useSelector } from 'react-redux';
const VisibleTodoList = () => {
const visibleTodos = useSelector(getVisibleTodos);
// Render UI dựa trên visibleTodos
};
Reselect là một công cụ hữu ích trong việc quản lý và truy xuất state trong các ứng dụng Redux. Nó giúp tối ưu hóa hiệu suất bằng cách memoizing kết quả của các selector và cung cấp khả năng tái sử dụng và kết hợp các selector để xây dựng logic truy xuất dữ liệu phức tạp một cách dễ dàng và hiệu quả.
Làm thế nào để có thể tạo ref trong React?
Trong ReactJS, ref là một cách để truy cập trực tiếp một nút DOM hoặc một instance của một component trong React. Để tạo ref, bạn có thể sử dụng React.createRef() trong class components hoặc useRef() hook trong function components.
Trong class components, bạn thường tạo ref bằng cách sử dụng React.createRef() trong constructor và sau đó gắn ref này vào một phần tử JSX bằng cách sử dụng thuộc tính ref.
import React, { Component } from 'react';
class MyComponent extends Component {
constructor(props) {
super(props);
this.myRef = React.createRef();
}
componentDidMount() {
console.log(this.myRef.current); // Truy cập đến nút DOM hoặc component instance
}
render() {
return <div ref={this.myRef}>Hello, World!</div>;
}
}
Trong function components, bạn có thể sử dụng useRef() hook để tạo ref. useRef trả về một đối tượng ref mà bạn có thể gắn vào phần tử JSX.
import React, { useRef, useEffect } from 'react';
function MyComponent() {
const myRef = useRef(null);
useEffect(() => {
console.log(myRef.current); // Truy cập đến nút DOM
}, []);
return <div ref={myRef}>Hello, World!</div>;
}
Trong cả hai trường hợp, ref sẽ có một thuộc tính current mà thông qua đó bạn có thể truy cập đến nút DOM hoặc instance của component mà ref đã được gắn vào.
ref chỉ khi thực sự cần thiết, ví dụ như để quản lý focus, chọn văn bản, hoặc thực hiện các thao tác truyền thống với DOM mà không thể thực hiện thông qua cơ chế state và props của React.ref để "hỏi" về trạng thái của component con, thay vào đó, nên sử dụng các cơ chế dữ liệu từ trên xuống như props hoặc context.Tóm lại, ref trong ReactJS là một công cụ mạnh mẽ cho phép bạn truy cập trực tiếp vào nút DOM hoặc instance của component, nhưng nên được sử dụng một cách cẩn thận và hợp lý.
Làm sao để React build ở chế độ production và chúng có lợi ích như thế nào?
Trong React, việc build ứng dụng ở chế độ Production là một bước quan trọng để chuẩn bị triển khai ứng dụng của bạn lên môi trường sản xuất. Build ở chế độ Production giúp tối ưu hóa ứng dụng về mặt hiệu suất và bảo mật.
Để build một ứng dụng React ở chế độ Production, bạn thường sử dụng các công cụ như Webpack hoặc các script được cung cấp bởi create-react-app (nếu bạn sử dụng boilerplate này để khởi tạo dự án). Dưới đây là các bước cơ bản:
Sử dụng create-react-app:
Nếu ứng dụng của bạn được khởi tạo bằng create-react-app, bạn có thể sử dụng script build đã được cấu hình sẵn:
npm run build
Hoặc nếu bạn sử dụng yarn:
yarn build
Lệnh này sẽ tạo ra một thư mục build chứa các tệp đã được tối ưu hóa cho môi trường sản xuất.
Cấu hình Webpack:
Nếu bạn tự cấu hình Webpack, bạn cần đảm bảo rằng bạn đã thiết lập đúng các plugin và loader để tối ưu hóa mã nguồn, như UglifyJsPlugin để minify mã JavaScript, MiniCssExtractPlugin để tối ưu hóa CSS, và các cấu hình khác để tối ưu hóa hình ảnh và tài nguyên.
Thiết lập biến môi trường:
Đảm bảo rằng bạn đã thiết lập biến môi trường NODE_ENV thành production. Điều này sẽ báo cho React biết rằng bạn đang build ứng dụng cho môi trường sản xuất, và React sẽ tối ưu hóa ứng dụng cho mục đích này.
process.env.NODE_ENV = 'production';
Việc build ứng dụng React ở chế độ Production là một bước không thể thiếu trước khi triển khai ứng dụng, giúp đảm bảo rằng người dùng cuối có trải nghiệm tốt nhất khi sử dụng ứng dụng của bạn.
PureComponent trong React là gì?
PureComponent trong React là một lớp component mở rộng từ Component với một khác biệt chính: PureComponent tự động thực hiện một so sánh nông (shallow comparison) trên props và state của nó để quyết định xem component có cần được cập nhật hay không. Điều này giúp tối ưu hóa hiệu suất ứng dụng bằng cách tránh các lần re-render không cần thiết.
PureComponent:PureComponent thực hiện một so sánh nông trên cả props và state. Nếu không có sự thay đổi nào được phát hiện, component sẽ không được cập nhật. So sánh nông có nghĩa là chỉ so sánh giá trị nguyên thủy và địa chỉ tham chiếu của đối tượng/ mảng, chứ không so sánh sâu các giá trị bên trong đối tượng hoặc mảng.PureComponent giúp tối ưu hóa hiệu suất, đặc biệt là trong các ứng dụng lớn và phức tạp.PureComponent, bạn cần đảm bảo rằng tất cả các props và state được sử dụng trong component đều là các giá trị nguyên thủy hoặc đối tượng/ mảng mà không thay đổi cấu trúc bên trong. Nếu không, PureComponent có thể không phát hiện được sự thay đổi và từ chối cập nhật component một cách không mong muốn.PureComponent:import React, { PureComponent } from 'react';
class MyComponent extends PureComponent {
constructor(props) {
super(props);
this.state = { count: 0 };
}
incrementCount = () => {
this.setState({ count: this.state.count + 1 });
};
render() {
console.log('Component re-rendered!');
return (
<div>
<p>Count: {this.state.count}</p>
<button onClick={this.incrementCount}>Increment</button>
</div>
);
}
}
Trong ví dụ trên, MyComponent sẽ chỉ được re-render khi state.count thực sự thay đổi. Nếu có bất kỳ hành động nào khác không thay đổi giá trị của state.count, PureComponent sẽ ngăn chặn việc re-render không cần thiết.
Tóm lại, PureComponent là một công cụ hữu ích trong React để tối ưu hóa hiệu suất ứng dụng bằng cách giảm số lượng lần re-render không cần thiết thông qua việc thực hiện so sánh nông trên props và state.
Refs được sử dụng như thế nào trong React?
Trong React, refs là một cách để truy cập trực tiếp một nút DOM hoặc một instance của một component từ bên trong component React. Refs thường được sử dụng khi bạn cần thực hiện các thao tác trực tiếp trên DOM hoặc khi cần truy cập trực tiếp đến một component con từ một component cha.
Trong React, bạn có thể tạo refs bằng cách sử dụng React.createRef() (trong React 16.3 trở lên) hoặc bằng cách sử dụng callback refs.
React.createRef()class MyComponent extends React.Component {
constructor(props) {
super(props);
this.myRef = React.createRef();
}
render() {
return <div ref={this.myRef} />;
}
}
class MyComponent extends React.Component {
setMyRef = (element) => {
this.myRef = element;
}
render() {
return <div ref={this.setMyRef} />;
}
}
refs cho việc thực hiện logic xây dựng giao diện. Thay vào đó, hãy sử dụng state và props.refs một cách cẩn thận vì việc truy cập trực tiếp và thay đổi DOM có thể làm giảm hiệu suất và khả năng dự đoán của ứng dụng.useRef để tạo refs.Refs cung cấp một cách mạnh mẽ để tương tác với các phần tử DOM hoặc component con, nhưng cần được sử dụng một cách thông minh để không làm mất đi lợi ích của việc React quản lý DOM.
Ưu điểm của React là gì?
ReactJS, một thư viện JavaScript mạnh mẽ và linh hoạt cho việc xây dựng giao diện người dùng (UI), mang lại nhiều ưu điểm cho các nhà phát triển và doanh nghiệp. Dưới đây là một số ưu điểm chính của ReactJS:
ReactJS sử dụng kiến trúc dựa trên component, giúp phát triển các ứng dụng dễ dàng và hiệu quả. Mỗi component có thể quản lý trạng thái riêng của mình và được tái sử dụng ở nhiều nơi trong ứng dụng, giúp tăng cường tính bảo trì và tái sử dụng mã.
React sử dụng Virtual DOM để tối ưu hóa hiệu suất bằng cách giảm thiểu số lượng cập nhật DOM thực tế. Khi trạng thái của một component thay đổi, React sẽ cập nhật Virtual DOM trước, sau đó sử dụng thuật toán diffing để xác định những thay đổi cần thiết trên DOM thực tế, giúp tăng tốc độ và hiệu suất của ứng dụng.
ReactJS sử dụng mô hình dữ liệu một chiều (one-way data binding), giúp kiểm soát dòng dữ liệu trong ứng dụng và làm cho ứng dụng dễ debug hơn. Mô hình này cũng giúp các nhà phát triển dễ dàng theo dõi các thay đổi trong ứng dụng, từ đó tối ưu hóa và bảo trì dễ dàng hơn.
JSX là một cú pháp mở rộng cho JavaScript, cho phép viết cấu trúc UI trong mã JavaScript một cách dễ dàng và rõ ràng. JSX giúp mã nguồn dễ đọc và viết hơn, đồng thời cung cấp khả năng kiểm tra và tối ưu hóa mã nguồn tốt hơn.
React được phát triển và bảo trì bởi Facebook cùng với sự đóng góp từ một cộng đồng lớn các nhà phát triển. Điều này đảm bảo rằng React luôn được cập nhật với các tính năng mới và hỗ trợ tốt cho các nhà phát triển.
React có thể được tích hợp với các thư viện và framework khác như Redux, React Router, hoặc thậm chí là Angular, giúp xây dựng các ứng dụng phức tạp và mạnh mẽ. Tính linh hoạt này cho phép các nhà phát triển chọn lựa công nghệ phù hợp nhất cho dự án của mình.
React có thể render trên server (sử dụng Node.js) giúp cải thiện khả năng tương thích với công cụ tìm kiếm (SEO) của ứng dụng web, một lợi thế lớn cho các dự án cần tối ưu hóa SEO.
Tóm lại, ReactJS mang lại nhiều lợi ích như kiến trúc dựa trên component, hiệu suất cao nhờ Virtual DOM, mô hình dữ liệu một chiều, cú pháp JSX dễ sử dụng, sự hỗ trợ mạnh mẽ từ cộng đồng, tính linh hoạt và khả năng tương thích tốt với SEO. Những ưu điểm này làm cho React trở thành một lựa chọn hàng đầu cho việc phát triển giao diện người dùng động và hiện đại.
Life Cycle trong React hoạt động như thế nào?
Life Cycle (Vòng đời) trong React mô tả quá trình mà một component trải qua từ khi được khởi tạo cho đến khi bị loại bỏ khỏi DOM. Vòng đời của một component trong React được chia thành ba giai đoạn chính: Mounting, Updating, và Unmounting.
Mounting là giai đoạn mà component được tạo ra và chèn vào DOM. Các phương thức life cycle chính trong giai đoạn này bao gồm:
constructor(): Phương thức đầu tiên được gọi trong quá trình mounting. Thường được sử dụng để khởi tạo state và bind các phương thức event handler.static getDerivedStateFromProps(): Được gọi ngay sau constructor và trước render(). Cho phép component cập nhật state dựa trên props ban đầu hoặc thay đổi props.render(): Phương thức bắt buộc phải có. Trả về các element React mà bạn muốn hiển thị trên UI.componentDidMount(): Được gọi sau khi component được chèn vào DOM. Thường được sử dụng để thực hiện các yêu cầu mạng, thiết lập các subscription, hoặc thao tác DOM.Updating là giai đoạn mà component được cập nhật do thay đổi props hoặc state. Các phương thức life cycle trong giai đoạn này bao gồm:
static getDerivedStateFromProps(): Cũng được gọi trong giai đoạn này để cập nhật state dựa trên thay đổi props.shouldComponentUpdate(): Cho phép bạn quyết định xem component có nên re-render hay không dựa trên thay đổi của props hoặc state.render(): Được gọi lại để re-render UI với dữ liệu mới.getSnapshotBeforeUpdate(): Được gọi trước khi thay đổi được áp dụng vào DOM. Dùng để thu thập thông tin từ DOM trước khi nó được thay đổi.componentDidUpdate(): Được gọi sau khi component được cập nhật và re-render. Dùng để thực hiện các thao tác sau khi component được cập nhật.Unmounting là giai đoạn cuối cùng của vòng đời component, khi component bị loại bỏ khỏi DOM. Có một phương thức life cycle trong giai đoạn này:
componentWillUnmount(): Được gọi trước khi component bị loại bỏ khỏi DOM. Thường được sử dụng để dọn dẹp các subscription, hủy bỏ các yêu cầu mạng, và thực hiện các tác vụ dọn dẹp.Vòng đời của component trong React giúp bạn quản lý và kiểm soát quá trình render, cập nhật, và loại bỏ component một cách hiệu quả, đảm bảo rằng ứng dụng của bạn hoạt động mượt mà và hiệu quả.
Làm thế nào để bạn chặn callback của 1 event trong React?
Để chặn callback của một event trong React, bạn có thể sử dụng phương thức preventDefault() hoặc stopPropagation() trên đối tượng event được truyền vào hàm xử lý sự kiện (event handler).
preventDefault()Phương thức preventDefault() được sử dụng để ngăn chặn hành vi mặc định của một sự kiện. Điều này hữu ích khi bạn muốn chặn các hành vi mặc định của trình duyệt, như việc gửi một form khi nhấn submit, hoặc chuyển trang khi nhấn vào một liên kết.
Ví dụ:
function handleSubmit(event) {
event.preventDefault();
// Logic xử lý khi form được submit
}
return (
<form onSubmit={handleSubmit}>
{/* Các thành phần của form */}
<button type="submit">Submit</button>
</form>
);
Trong ví dụ trên, preventDefault() được gọi trong hàm handleSubmit để ngăn chặn việc form được gửi đi một cách mặc định.
stopPropagation()Phương thức stopPropagation() được sử dụng để ngăn chặn việc lan truyền của một sự kiện từ một phần tử con lên các phần tử cha của nó trong DOM. Điều này hữu ích khi bạn muốn chặn một sự kiện ở một phần tử con mà không muốn sự kiện đó ảnh hưởng đến các phần tử cha.
Ví dụ:
function handleClickChild(event) {
event.stopPropagation();
// Logic xử lý khi phần tử con được click
}
function handleClickParent() {
// Logic này sẽ không được thực thi nếu phần tử con được click
}
return (
<div onClick={handleClickParent}>
<button onClick={handleClickChild}>Click Me</button>
</div>
);
Trong ví dụ trên, stopPropagation() được gọi trong hàm handleClickChild để ngăn chặn việc sự kiện click trên nút bấm lan truyền lên phần tử cha, do đó hàm handleClickParent sẽ không được thực thi khi nút bấm được click.
Sử dụng preventDefault() và stopPropagation() là hai cách phổ biến để chặn callback của một event trong React, tùy thuộc vào hành vi mà bạn muốn chặn.
SyntheticEvent trong React là gì?
SyntheticEvent trong ReactJS là một bao bọc cross-browser xung quanh native event của trình duyệt. Nó kết hợp hành vi của các sự kiện trình duyệt khác nhau thành một API chuẩn, đảm bảo rằng các sự kiện này hoạt động giống nhau trên tất cả các trình duyệt.
Khi bạn xử lý một sự kiện trong React, bạn không làm việc trực tiếp với native event. Thay vào đó, bạn làm việc với một instance của SyntheticEvent. React sẽ dịch native event thành SyntheticEvent và truyền nó vào hàm xử lý sự kiện của bạn.
function handleClick(event) {
console.log(event); // Đây là một SyntheticEvent
console.log(event.type); // "click"
}
function MyComponent() {
return <button onClick={handleClick}>Click me</button>;
}
Trong ví dụ trên, khi nút được click, hàm handleClick sẽ được gọi với một SyntheticEvent làm đối số. Bạn có thể truy cập các thuộc tính và phương thức của sự kiện giống như bạn làm với một native event, nhưng với sự đảm bảo rằng nó sẽ hoạt động giống nhau trên tất cả các trình duyệt.
Tóm lại, SyntheticEvent trong ReactJS giúp xử lý sự kiện trở nên nhất quán và dễ dàng hơn trên các trình duyệt khác nhau, đồng thời cung cấp hiệu suất tốt thông qua việc tái sử dụng sự kiện.
Element trong React là gì?
Element trong React là những khối xây dựng cơ bản nhất của ứng dụng React. Chúng mô tả những gì bạn muốn thấy trên màn hình. React elements là các đối tượng nhẹ và đơn giản mô tả một nút DOM, các thuộc tính của nó, và con của nó. Khác với trình duyệt DOM elements, React elements là các đối tượng thuần túy và dễ dàng tạo ra.
Để tạo một React element, bạn sử dụng React.createElement():
const element = React.createElement(
'h1',
{className: 'greeting'},
'Hello, world!'
);
Để render một element vào DOM, bạn sử dụng ReactDOM.render():
ReactDOM.render(element, document.getElementById('root'));
Trong ví dụ trên, ReactDOM.render() sẽ thay đổi nội dung của nút DOM với id='root' để hiển thị "Hello, world!".
Tóm lại, elements là cốt lõi của ứng dụng React, cho phép bạn mô tả giao diện người dùng của mình một cách đơn giản và hiệu quả.
Controlled component trong React là gì?
Trong React, một controlled component là một component mà giá trị của nó được quản lý bởi React state. Điều này có nghĩa là, thay vì để DOM quản lý trạng thái của dữ liệu nhập (như trong HTML truyền thống), trong React, component chứa form (ví dụ: <input>, <textarea>, và <select>) sẽ lưu trữ trạng thái trong state và cập nhật nó dựa trên mỗi thay đổi từ người dùng thông qua sự kiện.
onChange) sẽ được kích hoạt, và state sẽ được cập nhật dựa trên giá trị mới.class ControlledComponent extends React.Component {
constructor(props) {
super(props);
this.state = {value: ''};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('A name was submitted: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" value={this.state.value} onChange={this.handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
Trong ví dụ trên, <input> là một controlled component vì giá trị của nó được kiểm soát bởi React state thông qua this.state.value và được cập nhật bằng this.handleChange.
Controlled components cung cấp một cách mạnh mẽ và linh hoạt để xây dựng các form trong React, giúp quản lý dữ liệu nhập một cách hiệu quả và nhất quán.
Kể tên một số middleware của Redux mà bạn biết?
Trong Redux, middleware là một tầng trung gian cho phép bạn viết logic có thể tương tác với mỗi action được gửi đến store trước khi nó đạt đến reducer. Middleware có thể được sử dụng để xử lý logging, báo cáo về các lỗi, thực hiện các yêu cầu bất đồng bộ, và nhiều hơn nữa. Dưới đây là một số middleware phổ biến trong Redux:
Các middleware này giúp mở rộng khả năng của Redux và cho phép xử lý các tác vụ phức tạp một cách dễ dàng hơn.
Sự khác nhau giữa class component và functional component trong Reactjs là gì?
Trong React, có hai loại chính để xây dựng components: class components và functional components. Mỗi loại có đặc điểm và cách sử dụng riêng.
Class ComponentsClass components được định nghĩa bằng cách sử dụng ES6 classes. Chúng thường được sử dụng khi cần trạng thái (state) hoặc các phương thức lifecycle.Class components cho phép bạn sử dụng các phương thức lifecycle như componentDidMount, componentDidUpdate, và componentWillUnmount. Chúng cũng cho phép sử dụng this.state và this.setState để quản lý trạng thái.class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = { /* initial state */ };
}
componentDidMount() {
// Lifecycle method
}
render() {
return <div>{/* content */}</div>;
}
}
this: Trong class components, bạn cần chú ý đến việc binding this khi truyền phương thức của component như một callback.Functional ComponentsFunctional components được định nghĩa bằng cách sử dụng các hàm JavaScript thông thường. Trước đây, chúng thường được sử dụng cho các components không có trạng thái (stateless) hoặc không cần sử dụng đến lifecycle methods.functional components nay có thể sử dụng trạng thái và các tính năng khác của React thông qua useState, useEffect, và các hooks khác.function MyComponent(props) {
const [state, setState] = React.useState(initialState);
React.useEffect(() => {
// Side effects or lifecycle behavior
});
return <div>{/* content */}</div>;
}
Functional components thường đơn giản hơn và có thể có hiệu suất tốt hơn do không có overhead của các phương thức lifecycle mà class components mang lại.Class components sử dụng cú pháp ES6 class và cần kế thừa từ React.Component, trong khi functional components là các hàm JavaScript đơn giản.class components mới có thể sử dụng trạng thái và lifecycle methods. Giờ đây, functional components cũng có thể sử dụng các tính năng này thông qua hooks.this Binding: Chỉ class components mới cần quan tâm đến việc binding this, trong khi functional components không cần và thường dễ quản lý hơn.Class components và functional components đều có thể sử dụng để xây dựng UI trong React, nhưng với sự ra đời của Hooks, functional components trở nên mạnh mẽ hơn và được khuyến khích sử dụng do tính đơn giản và khả năng tái sử dụng mã cao. Class components vẫn còn hữu ích trong một số trường hợp, nhưng xu hướng hiện nay là chuyển dần sang sử dụng functional components.
Kể tên một số thư viện Flux phổ biến?
Flux là một kiến trúc ứng dụng được tạo ra bởi Facebook để sử dụng với thư viện React. Nó giúp tạo ra một luồng dữ liệu một chiều trong ứng dụng, giúp dễ dàng hơn trong việc theo dõi và quản lý trạng thái. Dưới đây là một số thư viện Flux phổ biến:
Các thư viện này cung cấp các cách tiếp cận khác nhau để triển khai kiến trúc Flux trong các ứng dụng React, giúp quản lý trạng thái và luồng dữ liệu một cách hiệu quả.
Cách để tránh phải liên kết với biến this trong các phương thức Event callback?
Để tránh phải liên kết với biến this trong các phương thức Event callback trong React, bạn có thể sử dụng một số cách sau:
Arrow functions không có context this riêng, nên this trong arrow functions sẽ tham chiếu đến context this của phạm vi bên ngoài (thường là component).
Ví dụ:
class MyComponent extends React.Component {
handleClick = () => {
console.log(this); // 'this' tham chiếu đến instance của MyComponent
}
render() {
return <button onClick={this.handleClick}>Click me</button>;
}
}
Khi truyền callback, bạn có thể sử dụng arrow function ngay tại chỗ để đảm bảo this được liên kết đúng cách.
Ví dụ:
class MyComponent extends React.Component {
handleClick() {
console.log(this); // 'this' tham chiếu đến instance của MyComponent
}
render() {
return <button onClick={() => this.handleClick()}>Click me</button>;
}
}
Đây là một tính năng của ES6+ cho phép bạn định nghĩa các phương thức của class dưới dạng arrow functions ngay trong phần khai báo của class.
Ví dụ:
class MyComponent extends React.Component {
handleClick = () => {
console.log(this); // 'this' tham chiếu đến instance của MyComponent
}
render() {
return <button onClick={this.handleClick}>Click me</button>;
}
}
Nếu bạn sử dụng functional components, vấn đề liên kết this không còn tồn tại vì không có this trong functional components. Bạn có thể sử dụng hooks như useState và useEffect để quản lý trạng thái và lifecycle.
Ví dụ:
function MyComponent() {
const handleClick = () => {
console.log('Clicked!'); // Không cần 'this' vì đây là functional component
}
return <button onClick={handleClick}>Click me</button>;
}
Sử dụng các cách trên giúp bạn tránh phải liên kết với this trong các phương thức event callback, giúp mã nguồn gọn gàng và dễ quản lý hơn.
Tại sao chúng ta nên sử dụng Redux?
Redux là một thư viện JavaScript phổ biến được sử dụng để quản lý trạng thái (state) ứng dụng. Nó hoạt động tốt với các thư viện như React và Angular để xây dựng các ứng dụng phức tạp. Dưới đây là một số lý do tại sao Redux được sử dụng rộng rãi:
Redux cung cấp một cách tiếp cận dự đoán được và nhất quán để quản lý trạng thái ứng dụng. Trạng thái của toàn bộ ứng dụng được lưu trữ trong một cấu trúc dữ liệu duy nhất gọi là "store", giúp dễ dàng theo dõi các thay đổi trạng thái và quản lý trạng thái ứng dụng.
Redux hỗ trợ các công cụ như Redux DevTools, cho phép các nhà phát triển theo dõi các hành động, thay đổi trạng thái, và điều hướng qua lại giữa các trạng thái trước đó của ứng dụng. Điều này làm cho việc debug trở nên dễ dàng hơn và giúp phát triển ứng dụng nhanh chóng.
Vì Redux sử dụng các hàm thuần túy (pure functions) cho reducers và hành động (actions), nó làm cho việc kiểm tra và viết unit tests trở nên dễ dàng hơn. Bạn có thể dễ dàng kiểm tra các reducers với các trạng thái và hành động khác nhau mà không cần phụ thuộc vào bất kỳ thư viện hoặc framework nào khác.
Redux giúp đảm bảo rằng trạng thái ứng dụng thay đổi một cách nhất quán và dự đoán được thông qua các hành động đã định nghĩa trước. Điều này giúp tránh các lỗi không mong muốn và làm cho ứng dụng của bạn dễ hiểu và dễ quản lý hơn.
Redux giúp xây dựng kiến trúc ứng dụng mạnh mẽ bằng cách khuyến khích việc phân tách logic ứng dụng thành các phần nhỏ, có thể tái sử dụng. Điều này không chỉ giúp quản lý mã nguồn dễ dàng hơn mà còn tạo điều kiện cho việc phát triển và bảo trì ứng dụng.
Redux có một cộng đồng lớn và nhiều tài nguyên học tập, bao gồm tài liệu, hướng dẫn, và các khóa học. Điều này giúp việc học và sử dụng Redux trở nên dễ dàng hơn cho các nhà phát triển mới.
Tóm lại, Redux là một công cụ mạnh mẽ cho việc quản lý trạng thái ứng dụng, đặc biệt là khi xây dựng các ứng dụng lớn và phức tạp. Nó cung cấp một cách tiếp cận nhất quán và dễ kiểm soát, giúp ứng dụng của bạn dễ phát triển và bảo trì.
Flow trong React là gì?
Flow là một trình kiểm tra kiểu tĩnh (static type checker) cho JavaScript, được phát triển bởi Facebook. Nó được thiết kế để tìm và báo cáo về các lỗi tiềm ẩn trong mã JavaScript thông qua việc phân tích kiểu dữ liệu của biến, hàm và các cấu trúc khác trong codebase của bạn.
Flow hoạt động bằng cách phân tích mã nguồn để xác định kiểu dữ liệu của biến và hàm. Bạn có thể khai báo kiểu dữ liệu một cách rõ ràng trong mã nguồn hoặc để Flow suy luận (infer) kiểu dữ liệu dựa trên cách sử dụng biến và hàm. Flow sau đó sẽ kiểm tra xem các kiểu dữ liệu có được sử dụng một cách nhất quán trong suốt ứng dụng hay không và báo cáo lỗi nếu có sự không khớp.
// @flow
function square(n: number): number {
return n * n;
}
square("2"); // Flow sẽ báo lỗi tại đây vì "2" không phải là kiểu number
Trong ví dụ trên, Flow sẽ báo lỗi khi bạn cố gắng gọi hàm square với một chuỗi thay vì một số, vì kiểu dữ liệu đã được khai báo rõ ràng là number.
Flow là một công cụ hữu ích cho các nhà phát triển JavaScript nhằm đảm bảo tính nhất quán và độ chính xác của kiểu dữ liệu trong ứng dụng, giúp phát hiện và sửa chữa lỗi sớm trong quá trình phát triển. Sử dụng Flow có thể giúp cải thiện chất lượng mã nguồn và giảm thiểu lỗi khi ứng dụng được triển khai.
Tại sao nên dùng fragment thay vì div trong React?
Trong React, việc sử dụng fragment thay vì div là một phương pháp tối ưu hóa hiệu suất và cải thiện cấu trúc của mã nguồn. Dưới đây là một số lý do chính giải thích tại sao nên sử dụng fragment thay vì div:
React.Fragment với prop key, điều này rất hữu ích khi bạn cần render một danh sách các fragment như một phần của một collection.Việc sử dụng fragment thay vì div trong React giúp tối ưu hóa hiệu suất ứng dụng bằng cách giảm bớt số lượng nút DOM không cần thiết, cải thiện cấu trúc mã nguồn, và giảm thiểu các vấn đề về styling. Điều này làm cho ứng dụng của bạn trở nên hiệu quả và dễ bảo trì hơn.
So sánh điểm khác nhau của useRef và createRef trong React gì?
useRef và createRef trong React đều được sử dụng để tạo ra các refs, nhưng chúng có một số điểm khác biệt quan trọng:
useRef:useRef là một hook được giới thiệu trong React 16.8, cho phép bạn sử dụng refs trong function components.useRef trả về một đối tượng ref có thuộc tính current bền vững qua các lần re-render. Nghĩa là, nếu bạn gán một giá trị cho ref.current, giá trị đó sẽ giữ nguyên giữa các lần re-render, trừ khi bạn chủ động thay đổi nó.useRef thường được sử dụng trong function components vì class components không thể sử dụng hooks.useRef còn có thể lưu trữ bất kỳ giá trị nào bạn muốn giữ qua các lần re-render.createRef:createRef là một phương thức của React dùng để tạo refs trong class components.createRef sẽ tạo ra một đối tượng ref mới. Điều này có nghĩa là bạn không thể dựa vào createRef để giữ giá trị qua các lần re-render.createRef thường được sử dụng trong class components, nơi mà hooks không khả dụng.createRef thường được sử dụng để truy cập nút DOM hoặc component React sau khi component đã được mount.useRef giữ giá trị qua các lần re-render, trong khi createRef tạo ra một đối tượng ref mới mỗi lần component re-render.useRef được sử dụng trong function components, createRef được sử dụng trong class components.useRef có thể lưu trữ bất kỳ giá trị nào và thường được sử dụng để giữ giá trị qua các lần re-render, trong khi createRef chủ yếu được sử dụng để truy cập nút DOM hoặc component React.Tóm lại, useRef và createRef đều tạo ra các refs nhưng được sử dụng trong các loại component khác nhau và có cách hoạt động khác nhau liên quan đến vòng đời của refs trong quá trình re-render của component.
Portal trong React là gì?
Portal trong ReactJS là một tính năng cho phép bạn render các component vào một phần tử DOM nào đó nằm ngoài phạm vi DOM của component cha. Điều này rất hữu ích khi bạn cần render một component mà không muốn bị giới hạn bởi CSS hoặc vị trí DOM của component cha, ví dụ như các hộp thoại (modals), tooltips hoặc các thông báo toàn cục.
Để sử dụng portal, bạn sẽ sử dụng hàm ReactDOM.createPortal() từ thư viện ReactDOM. Hàm này nhận vào hai đối số:
Ví dụ:
import React from 'react';
import ReactDOM from 'react-dom';
class MyModal extends React.Component {
render() {
return ReactDOM.createPortal(
// Bất kỳ JSX nào bạn muốn render
<div className='modal'>
{/* Nội dung của modal */}
</div>,
// Nơi bạn muốn modal được render trong DOM
document.getElementById('modal-root')
);
}
}
Trong ví dụ trên, MyModal component sẽ được render vào phần tử có ID là modal-root trong DOM, bất kể vị trí của MyModal trong component tree của React.
Portal mang lại một cách mạnh mẽ và linh hoạt để quản lý việc render các component trong React, giúp bạn dễ dàng tạo ra các trải nghiệm người dùng phức tạp và tùy chỉnh.
Sự khác nhau giữa createElement và cloneElement trong React là gì?
Trong React, createElement và cloneElement là hai phương thức có chức năng khác nhau:
createElementcreateElement là một phương thức được sử dụng để tạo ra một React element mới từ một type (có thể là một tag HTML như 'div', 'span', hoặc một React component). Phương thức này thường được sử dụng khi bạn muốn tạo một element mà không cần viết JSX.createElement nhận vào ba tham số chính: type của element, một đối tượng chứa các props, và children của element đó.React.createElement('div', { className: 'my-div' }, 'Hello World');
createElement tạo ra một element div với class 'my-div' và chứa nội dung là 'Hello World'.cloneElementcloneElement là một phương thức được sử dụng để sao chép và trả về một bản sao của React element với các props mới và/hoặc children mới. Phương thức này thường được sử dụng khi bạn muốn tạo một bản sao của một element với một số thay đổi nhỏ mà không cần tạo một element mới từ đầu.cloneElement nhận vào ba tham số: element cần được sao chép, một đối tượng chứa các props mới, và children mới cho element đó.const element = <MyComponent foo="bar" />;
const clonedElement = React.cloneElement(element, { foo: 'baz' }, 'New Children');
cloneElement tạo ra một bản sao của MyComponent, thay đổi prop foo thành 'baz' và thay thế children bằng 'New Children'.createElement được sử dụng để tạo một element mới, trong khi cloneElement được sử dụng để sao chép và chỉnh sửa một element đã tồn tại.createElement tạo ra một element với props và children được xác định tại thời điểm tạo. cloneElement cho phép bạn thay đổi props và/hoặc children của một element đã có mà không ảnh hưởng đến element gốc.cloneElement có thể hiệu quả hơn khi bạn chỉ cần thay đổi một số ít props hoặc children, vì nó không yêu cầu tạo một element mới từ đầu.Cả createElement và cloneElement đều là những công cụ quan trọng trong React, giúp bạn quản lý việc tạo và sao chép các React element một cách linh hoạt.
Higher-Order component trong React là gì?
Higher-Order Component (HOC) trong React là một kỹ thuật nâng cao trong React để tái sử dụng logic component. Một HOC không phải là một phần của API React chính thức, mà là một mô hình phát sinh từ thành phần hợp thành của React. Nói một cách đơn giản, một HOC là một hàm nhận vào một component và trả về một component mới.
Một HOC thường được định nghĩa như một hàm JavaScript thuần túy. Đây là một ví dụ về cách tạo một HOC:
function withSubscription(WrappedComponent, selectData) {
return class extends React.Component {
constructor(props) {
super(props);
this.state = {
data: selectData(DataSource, props)
};
}
componentDidMount() {
// ... thêm logic đăng ký...
}
componentWillUnmount() {
// ... thêm logic hủy đăng ký...
}
render() {
// ... và render WrappedComponent với dữ liệu mới...
return <WrappedComponent data={this.state.data} {...this.props} />;
}
};
}
Trong ví dụ trên, withSubscription là một HOC nhận vào một WrappedComponent và một hàm selectData. Hàm này tạo ra một class component mới, quản lý việc đăng ký và hủy đăng ký đến một nguồn dữ liệu, và truyền dữ liệu đó như một prop đến WrappedComponent.
React.forwardRef.Tóm lại, Higher-Order Component là một mô hình mạnh mẽ trong React giúp bạn tạo ra các component có thể tái sử dụng, tách biệt logic không liên quan đến UI và chia sẻ logic đó giữa các component khác nhau.
Bạn thích hooks nào trong React? Hãy mô tả cách tạo một hooks bất kỳ.
Trong React, Hooks là một tính năng được giới thiệu từ phiên bản 16.8, cho phép bạn sử dụng state và các tính năng React khác mà không cần phải viết một class. Hooks mang lại nhiều lợi ích như việc giúp code trở nên gọn gàng hơn, dễ đọc và dễ bảo trì hơn. Một trong những Hooks mà tôi thích nhất là useState vì nó cung cấp một cách đơn giản để thêm trạng thái local vào trong function components.
useStateuseState là một Hook cơ bản cho phép bạn thêm trạng thái React vào trong function components. Khi bạn gọi useState trong một function component, React sẽ giữ giá trị này giữa các lần re-render của component.
Để sử dụng useState, bạn chỉ cần nhập nó từ React và gọi nó trong function component của mình:
import React, { useState } from 'react';
function Counter() {
// Khai báo một biến state mới, chúng ta gọi là "count"
const [count, setCount] = useState(0);
return (
<div>
<p>Bạn đã click {count} lần</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
Trong ví dụ trên, useState được gọi với giá trị khởi tạo là 0. Nó trả về một mảng với hai phần tử: giá trị hiện tại của trạng thái (count) và một hàm cho phép cập nhật giá trị đó (setCount). Khi bạn click vào nút, hàm setCount được gọi, dẫn đến việc component được re-render với giá trị mới của count.
Custom Hooks cho phép bạn tạo ra các Hooks riêng của mình, giúp tái sử dụng logic trạng thái giữa các components mà không cần phải dùng đến các pattern cao cấp như render props hay higher-order components.
Giả sử bạn muốn tạo một Hook để theo dõi vị trí chuột trong một component:
import { useState, useEffect } from 'react';
function useMousePosition() {
const [mousePosition, setMousePosition] = useState({ x: null, y: null });
useEffect(() => {
function handleMouseMove(event) {
setMousePosition({
x: event.clientX,
y: event.clientY
});
}
window.addEventListener('mousemove', handleMouseMove);
return () => {
window.removeEventListener('mousemove', handleMouseMove);
};
}, []);
return mousePosition;
}
Trong ví dụ trên, useMousePosition là một Custom Hook sử dụng useState để lưu trữ vị trí chuột và useEffect để thiết lập và dọn dẹp event listener. Bất kỳ component nào sử dụng useMousePosition sẽ có thể truy cập vào vị trí chuột hiện tại.
Tóm lại, Hooks trong React là một tính năng mạnh mẽ giúp bạn sử dụng state và các tính năng React khác trong function components. useState là một Hook cơ bản giúp quản lý trạng thái local, trong khi bạn cũng có thể tạo Custom Hooks để tái sử dụng logic trạng thái giữa các components.
Fragment trong React là gì?
Fragment trong React là một tính năng cho phép bạn nhóm nhiều phần tử con mà không cần thêm một nút DOM bổ sung vào cây DOM. Fragments giúp giữ cho DOM của bạn gọn gàng và tránh thêm các phần tử wrapper không cần thiết, giúp cải thiện hiệu suất và làm cho mã nguồn dễ quản lý hơn.
Bạn có thể sử dụng Fragments bằng cách sử dụng thẻ <React.Fragment> hoặc sử dụng cú pháp ngắn gọn <> ... </>.
Ví dụ sử dụng <React.Fragment>:
import React from 'react';
function MyComponent() {
return (
<React.Fragment>
<div>Child A</div>
<div>Child B</div>
</React.Fragment>
);
}
Ví dụ sử dụng cú pháp ngắn gọn:
import React from 'react';
function MyComponent() {
return (
<>
<div>Child A</div>
<div>Child B</div>
</>
);
}
Trong cả hai ví dụ trên, MyComponent sẽ render hai div mà không cần thêm một phần tử wrapper nào khác như div hoặc span vào DOM.
Fragments là một công cụ hữu ích trong React, giúp bạn viết mã nguồn sạch sẽ và hiệu quả hơn khi làm việc với các nhóm phần tử con trong component của mình.
Props drilling là gì?
Props drilling là một thuật ngữ trong React để mô tả việc truyền dữ liệu từ một component cha xuống các component con thông qua props qua nhiều cấp độ của component tree. Khi một component cha có một mảng dữ liệu hoặc một callback function mà một component con sâu trong cây cần truy cập, bạn phải "khoan" (drill) props xuống qua mỗi cấp độ của cây cho đến khi nó đến được component cần thiết.
Giả sử bạn có một component App chứa một component Layout, và Layout này chứa một component Sidebar. Nếu App có một state mà Sidebar cần truy cập, bạn sẽ phải truyền state đó như một prop từ App đến Layout, rồi từ Layout truyền tiếp đến Sidebar.
// App component
function App() {
const [user, setUser] = useState(null);
return <Layout user={user} />;
}
// Layout component
function Layout({ user }) {
return <Sidebar user={user} />;
}
// Sidebar component
function Sidebar({ user }) {
return <div>{user ? user.name : 'Guest'}</div>;
}
Để giải quyết vấn đề props drilling, React cung cấp một số giải pháp như:
Props drilling là một phần tự nhiên của việc phát triển ứng dụng React, nhưng việc hiểu rõ về nó và biết cách sử dụng các công cụ và kỹ thuật để giảm thiểu hoặc tránh nó có thể giúp bạn xây dựng các ứng dụng React hiệu quả và dễ bảo trì hơn.
Liệt kê một vài giới hạn của React?
React là một thư viện JavaScript mạnh mẽ và linh hoạt cho việc xây dựng giao diện người dùng, nhưng nó không phải là giải pháp hoàn hảo cho mọi vấn đề và có một số giới hạn:
Tóm lại, mặc dù React mang lại nhiều lợi ích cho việc phát triển giao diện người dùng, nhưng cũng có những giới hạn và thách thức mà các nhà phát triển cần xem xét khi chọn nó cho dự án của mình.
Sự khác biệt giữa VirtualDOM và ShadowDOM là gì?
Trong phát triển web, Virtual DOM và Shadow DOM là hai khái niệm quan trọng nhưng hoàn toàn khác biệt. Dưới đây là sự khác biệt chính giữa chúng:
Cả hai đều giúp cải thiện quy trình phát triển web nhưng hoạt động theo những cách thức và mục đích khác nhau.
Trong React, có nên cập nhật state trực tiếp không, tại sao?
Trong React, bạn không nên cập nhật state trực tiếp vì những lý do sau:
State trong React được coi là bất biến, nghĩa là bạn không nên thay đổi (mutate) nó trực tiếp. Thay vào đó, bạn nên sử dụng phương thức setState() (trong class components) hoặc hook useState() (trong function components) để cập nhật state. Việc này giúp React theo dõi các thay đổi và quản lý việc cập nhật DOM một cách hiệu quả.
React có thể gom chung nhiều lần cập nhật state vào một lần để tối ưu hóa hiệu suất. Khi bạn cập nhật state trực tiếp, React không thể phát hiện được sự thay đổi này và không thể quản lý việc cập nhật DOM một cách chính xác.
Khi sử dụng setState() hoặc useState(), React sẽ biết khi nào cần re-render component dựa trên sự thay đổi của state. Nếu bạn cập nhật state trực tiếp, component sẽ không re-render, và UI sẽ không phản ánh trạng thái mới của ứng dụng.
Cập nhật state trực tiếp có thể dẫn đến các lỗi khó phát hiện và khó debug vì nó vi phạm nguyên tắc dữ liệu bất biến mà React dựa trên. Điều này có thể gây ra hành vi không nhất quán trong ứng dụng của bạn.
React cung cấp các phương thức và hooks để cập nhật state một cách chính xác và kiểm soát được. Việc sử dụng các công cụ này giúp đảm bảo rằng ứng dụng của bạn hoạt động như mong đợi và tận dụng được các tính năng tối ưu hóa của React.
Tóm lại, bạn không nên cập nhật state trực tiếp trong React vì nó vi phạm nguyên tắc bất biến của state, làm giảm khả năng React quản lý việc cập nhật UI, và có thể dẫn đến các lỗi không mong muốn trong ứng dụng của bạn.
Làm cách nào để liên kết các phương thức hoặc event handler trong lệnh callback JSX?
Trong React, việc liên kết các phương thức hoặc event handler trong lệnh callback JSX là quan trọng để đảm bảo rằng this trong phương thức đó tham chiếu đúng đến instance của component. Dưới đây là một số cách để liên kết các phương thức hoặc event handler:
Arrow functions không có context this riêng, nên khi bạn sử dụng chúng trong JSX, this sẽ tham chiếu đến context bên ngoài - thường là instance của component. Điều này giúp tránh việc phải liên kết this một cách rõ ràng.
class MyComponent extends React.Component {
myMethod() {
console.log(this); // Tham chiếu đúng đến instance của MyComponent
}
render() {
return <button onClick={() => this.myMethod()}>Click me</button>;
}
}
.bind() trong JSXBạn có thể sử dụng phương thức .bind() để rõ ràng liên kết this với phương thức hoặc event handler khi truyền nó vào JSX. Tuy nhiên, cách này có thể gây ra việc tạo ra một hàm mới mỗi lần component render, ảnh hưởng đến hiệu suất.
class MyComponent extends React.Component {
myMethod() {
console.log(this); // Tham chiếu đúng đến instance của MyComponent
}
render() {
return <button onClick={this.myMethod.bind(this)}>Click me</button>;
}
}
Một cách hiệu quả hơn để liên kết this là sử dụng .bind() trong constructor của component. Cách này chỉ tạo ra một hàm liên kết duy nhất, không phụ thuộc vào số lần render.
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.myMethod = this.myMethod.bind(this);
}
myMethod() {
console.log(this); // Tham chiếu đúng đến instance của MyComponent
}
render() {
return <button onClick={this.myMethod}>Click me</button>;
}
}
Nếu bạn sử dụng Babel hoặc một trình biên dịch hỗ trợ class fields (đề xuất ECMAScript), bạn có thể định nghĩa phương thức hoặc event handler dưới dạng arrow function ngay trong class component. Cách này tự động liên kết this mà không cần phải sử dụng .bind().
class MyComponent extends React.Component {
myMethod = () => {
console.log(this); // Tham chiếu đúng đến instance của MyComponent
}
render() {
return <button onClick={this.myMethod}>Click me</button>;
}
}
Sử dụng một trong các cách trên giúp đảm bảo rằng this trong các phương thức hoặc event handler của bạn được liên kết đúng cách, cho phép bạn truy cập this.props, this.state, và các phương thức khác của component một cách an toàn.
StrictMode trong React là gì?
StrictMode trong React là một công cụ phát triển giúp phát hiện các vấn đề tiềm ẩn trong ứng dụng của bạn. Bằng cách bao bọc các component với StrictMode, React sẽ kích hoạt các kiểm tra và cảnh báo bổ sung cho các component con của nó. StrictMode không ảnh hưởng đến việc render của ứng dụng nhưng sẽ giúp bạn nhận biết về các sử dụng không an toàn của API, các vấn đề về side effects, lỗi sử dụng lỗi thời và các vấn đề khác mà có thể làm cho ứng dụng của bạn trở nên khó bảo trì hơn trong tương lai.
render bằng cách gọi hai lần các phương thức vòng đời và hàm tạo (constructor) trong giai đoạn phát triển.findDOMNode, mà có thể dẫn đến việc viết mã không tối ưu.context không đúng cách.StrictMode được sử dụng bằng cách bao bọc các component với nó. Bạn có thể bao bọc toàn bộ ứng dụng của mình hoặc chỉ một phần của ứng dụng:
import React from 'react';
function App() {
return (
<React.StrictMode>
<MyComponent />
</React.StrictMode>
);
}
Lưu ý rằng StrictMode chỉ kiểm tra các component con của nó, không kiểm tra chính nó. Nó cũng chỉ hoạt động trong môi trường phát triển; các kiểm tra và cảnh báo sẽ không xuất hiện trong sản phẩm cuối.
Tóm lại, StrictMode là một công cụ hữu ích trong React giúp bạn viết mã tốt hơn và phát hiện sớm các vấn đề tiềm ẩn, từ đó giúp ứng dụng của bạn trở nên bền vững và dễ bảo trì hơn.
Forwarding Refs trong React đển làm gì?
Forwarding Refs trong React là một kỹ thuật cho phép bạn chuyển một ref tự động qua một component để nó có thể truy cập đến một phần tử DOM con hoặc một instance của class component con. Điều này thường cần thiết khi bạn muốn một component cha có thể tương tác trực tiếp với một phần tử DOM hoặc component con mà không cần phải thêm các props trung gian hoặc logic bổ sung.
Để sử dụng forwarding refs, bạn sẽ sử dụng hàm React.forwardRef để tạo một component. Hàm này nhận vào một hàm render và trả về một component React. Hàm render này nhận vào props và ref như là tham số và trả về một React element.
Ví dụ:
const MyInput = React.forwardRef((props, ref) => (
<input ref={ref} {...props} />
));
class ParentComponent extends React.Component {
constructor(props) {
super(props);
this.inputRef = React.createRef();
}
focusInput = () => {
this.inputRef.current.focus();
};
render() {
return (
<>
<MyInput ref={this.inputRef} />
<button onClick={this.focusInput}>Focus the input</button>
</>
);
}
}
Trong ví dụ trên, MyInput là một component được tạo ra bằng React.forwardRef. Khi ParentComponent render MyInput, nó chuyển ref mà nó tạo ra (this.inputRef) vào MyInput. MyInput sau đó chuyển ref này vào phần tử input DOM. Khi người dùng nhấn vào nút "Focus the input", phương thức focusInput của ParentComponent sẽ được gọi, và input sẽ được focus.
Forwarding refs là một công cụ hữu ích trong React, đặc biệt khi bạn cần tương tác với phần tử DOM hoặc quản lý focus, chọn văn bản, hoặc thực hiện các hoạt động tương tự mà không muốn vi phạm nguyên tắc của dữ liệu xuôi (data down, actions up).
Hàm setState trong React là đồng bộ hay bất đồng bộ? Tại sao?
Hàm setState trong Reactjs thường được coi là bất đồng bộ, vì React có thể gom chung nhiều lần gọi setState vào một lần cập nhật duy nhất để tối ưu hóa hiệu suất. Điều này có nghĩa là React có thể trì hoãn việc thực thi setState và sau đó cập nhật nhiều state cùng một lúc.
setState là bất đồng bộ?setState và áp dụng chúng cùng một lúc trong một chu trình cập nhật.setState.setState?Callback Function: setState nhận một hàm callback làm tham số thứ hai, được gọi sau khi state đã được cập nhật và component đã re-render.
this.setState({ myState: newValue }, () => {
console.log(this.state.myState); // Giá trị mới của state
});
Lifecycle Methods: Sử dụng các phương thức vòng đời của component như componentDidUpdate để làm việc với state sau khi nó đã được cập nhật.
Tóm lại, setState hoạt động một cách bất đồng bộ trong hầu hết các trường hợp để tối ưu hóa hiệu suất ứng dụng. Điều này đôi khi có thể gây ra nhầm lẫn, nhưng có thể được xử lý thông qua việc sử dụng hàm callback hoặc các phương thức vòng đời của component.
Làm thế nào để việc render của React hoạt động chính xác khi chúng ta gọi setState?
Trong React, việc render hoạt động chính xác khi gọi setState dựa trên một số nguyên tắc cơ bản của thư viện này:
setStateKhi bạn gọi setState, React sẽ lên lịch một cập nhật trạng thái cho component. Tuy nhiên, setState không cập nhật trạng thái ngay lập tức mà thay vào đó, nó khởi tạo một quá trình cập nhật bất đồng bộ. Điều này có nghĩa là React có thể gom chung nhiều lần gọi setState vào một lần cập nhật duy nhất để tối ưu hóa hiệu suất.
Sau khi setState được gọi, React sẽ thực hiện các bước sau:
Trong class components, việc gọi setState sẽ kích hoạt một số phương thức vòng đời:
shouldComponentUpdate: Cho phép bạn quyết định xem component có nên cập nhật hay không dựa trên sự thay đổi của props hoặc state.componentWillUpdate/UNSAFE_componentWillUpdate: Được gọi trước khi cập nhật xảy ra (được coi là lỗi thời và không khuyến khích sử dụng).componentDidUpdate: Được gọi sau khi component đã được cập nhật trong DOM.Trong function components, việc cập nhật trạng thái được quản lý thông qua hooks như useState và useEffect.
React thực hiện "batch updates" để tối ưu hóa quá trình cập nhật. Điều này có nghĩa là nhiều lần gọi setState có thể được gom chung và xử lý trong một lần cập nhật duy nhất, giúp giảm số lượng re-renders và tăng hiệu suất.
Bạn không bao giờ nên thay đổi trạng thái trực tiếp bằng cách gán giá trị mới cho this.state vì React sẽ không biết được sự thay đổi này và không thể quản lý việc cập nhật DOM một cách chính xác.
Tóm lại, việc render trong React hoạt động chính xác khi gọi setState nhờ vào việc quản lý trạng thái một cách bất đồng bộ, quá trình reconciliation để xác định những thay đổi cần thiết trong DOM, và việc tối ưu hóa cập nhật thông qua batch updates.
Keys trong React được dùng để làm gì?
Trong React, key là một thuộc tính đặc biệt mà bạn nên bao gồm khi tạo danh sách các phần tử từ một mảng dữ liệu. Key giúp React xác định các phần tử nào đã thay đổi, được thêm vào, hoặc bị xóa, và nó là một phần quan trọng trong việc tối ưu hóa việc cập nhật và tái render của danh sách.
Hiệu Suất: Khi render một danh sách, React sử dụng các key để so sánh các phần tử giữa các lần render khác nhau. Nếu React phát hiện ra rằng một phần tử có key đã tồn tại trước đó, nó sẽ cập nhật phần tử đó thay vì tạo một phần tử mới, giúp cải thiện hiệu suất bằng cách tránh tái render không cần thiết.
Tái Sử Dụng và Sắp Xếp: Khi danh sách thay đổi, React có thể tái sử dụng các phần tử có cùng key để cập nhật UI một cách nhanh chóng. Điều này đặc biệt hữu ích khi bạn cần sắp xếp hoặc lọc danh sách mà không muốn mất trạng thái bên trong các phần tử.
Stability: Key giúp React duy trì sự ổn định của danh sách khi dữ liệu thay đổi, đảm bảo rằng mỗi phần tử được theo dõi một cách chính xác qua các lần cập nhật.
Khi render một danh sách các phần tử, bạn nên cung cấp một key duy nhất cho mỗi phần tử trong danh sách. Key này thường là một ID duy nhất từ dữ liệu của bạn, nhưng có thể là bất kỳ giá trị nào duy nhất đối với mỗi phần tử.
const listItems = data.map((item) =>
<li key={item.id}>
{item.text}
</li>
);
Trong ví dụ trên, item.id là một giá trị duy nhất được sử dụng làm key cho mỗi phần tử li.
key nếu danh sách có thể thay đổi, vì điều này có thể gây ra các vấn đề về hiệu suất và hành vi không mong muốn.Key phải là duy nhất trong phạm vi của danh sách, nhưng không cần phải là duy nhất toàn cục trong toàn bộ ứng dụng.Key là một công cụ quan trọng giúp React quản lý danh sách một cách hiệu quả, đảm bảo rằng các cập nhật UI diễn ra nhanh chóng và chính xác.
Trong React uncontrolled component là gì?
Uncontrolled component trong React là một mẫu component mà trạng thái của nó không được quản lý bởi React. Trong uncontrolled components, dữ liệu form như giá trị của một input được xử lý bởi DOM thay vì bởi state trong component. Điều này có nghĩa là bạn sử dụng DOM như là "nguồn sự thật" để lấy giá trị hiện tại của input, thay vì lưu trữ giá trị đó trong state.
Để tạo một uncontrolled component, bạn thường sử dụng ref để truy cập trực tiếp đến phần tử DOM, thay vì sử dụng state và props để kiểm soát các sự kiện như onChange. ref được sử dụng để lấy giá trị từ form khi cần thiết, chẳng hạn như khi form được gửi đi.
Ví dụ:
class MyForm extends React.Component {
constructor(props) {
super(props);
this.inputRef = React.createRef();
}
handleSubmit = (event) => {
alert('A name was submitted: ' + this.inputRef.current.value);
event.preventDefault();
};
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" ref={this.inputRef} />
</label>
<button type="submit">Submit</button>
</form>
);
}
}
Trong ví dụ trên, MyForm là một uncontrolled component vì nó sử dụng ref để lấy giá trị của input, thay vì quản lý giá trị đó thông qua state.
Lợi Ích:
Nhược Điểm:
Uncontrolled components thường được sử dụng khi bạn muốn tương tác trực tiếp với DOM hoặc khi bạn muốn giảm bớt số lượng logic trong component của mình. Tuy nhiên, trong hầu hết các trường hợp, controlled components (trạng thái được quản lý bởi React) được ưa chuộng hơn vì chúng cung cấp khả năng kiểm soát và linh hoạt cao hơn.
mapStateToProps và mapDispatchToProps trong redux là gì?
Trong Redux, mapStateToProps và mapDispatchToProps là hai hàm helper được sử dụng để kết nối một component React với Redux store. Chúng cho phép bạn lấy trạng thái và hành động từ store và chuyển chúng dưới dạng props đến component của bạn.
mapStateToProps là một hàm cho phép bạn trích xuất dữ liệu từ Redux store và chuyển chúng dưới dạng props đến component React của bạn. Hàm này nhận vào state của Redux store như là tham số đầu tiên và trả về một đối tượng chứa các props mà bạn muốn truyền vào component. Khi store thay đổi, mapStateToProps sẽ được gọi và component sẽ được render lại với các props mới.
function mapStateToProps(state) {
return {
todos: state.todos
};
}
Trong ví dụ trên, mapStateToProps trích xuất todos từ state của Redux store và chuyển nó như một prop đến component.
mapDispatchToProps là một hàm cho phép bạn tạo ra các props callback mà khi được gọi sẽ dispatch một action đến Redux store. Hàm này nhận vào dispatch của Redux store như là tham số đầu tiên và trả về một đối tượng chứa các props mà bạn muốn truyền vào component. Các props này thường là các hàm mà khi được gọi sẽ dispatch một action để cập nhật trạng thái của store.
function mapDispatchToProps(dispatch) {
return {
addTodo: (text) => dispatch(addTodoAction(text))
};
}
Trong ví dụ trên, mapDispatchToProps tạo ra một prop addTodo mà khi được gọi sẽ dispatch một action addTodoAction đến store.
connectmapStateToProps và mapDispatchToProps thường được sử dụng cùng với hàm connect từ thư viện react-redux để kết nối component với Redux store.
import { connect } from 'react-redux';
// Component của bạn
function TodoList(props) {
// Sử dụng props.todos và props.addTodo trong component
}
// Kết nối Redux store với TodoList component
export default connect(mapStateToProps, mapDispatchToProps)(TodoList);
Khi sử dụng connect, mapStateToProps và mapDispatchToProps giúp định nghĩa cách mà dữ liệu và hành động từ store được chuyển đến component dưới dạng props, giúp component có thể tương tác với Redux store một cách dễ dàng và linh hoạt.
Hãy phân biệt Dom thật (real dom) và Dom ảo (virtual dom)?
Real DOM và Virtual DOM là hai khái niệm quan trọng trong phát triển web, đặc biệt là khi làm việc với các thư viện như React. Dưới đây là sự phân biệt chính giữa chúng:
Real DOM là cấu trúc dữ liệu mà trình duyệt sử dụng để render giao diện người dùng, trong khi Virtual DOM là một kỹ thuật được sử dụng trong các thư viện như React để tối ưu hóa việc cập nhật giao diện. Virtual DOM giúp cải thiện hiệu suất bằng cách giảm thiểu số lượng cập nhật trực tiếp trên Real DOM, từ đó mang lại trải nghiệm người dùng mượt mà và hiệu quả hơn.
Store trong redux là gì?
Store trong Redux là một đối tượng chứa trạng thái (state) của toàn bộ ứng dụng. Nó đóng vai trò là "single source of truth" (nguồn sự thật duy nhất) vì nó chứa tất cả dữ liệu cần thiết cho UI của ứng dụng. Store trong Redux có một số đặc điểm và chức năng chính sau:
getState() để truy cập trạng thái hiện tại của ứng dụng.dispatch(action), nơi action là một đối tượng mô tả sự thay đổi muốn thực hiện.subscribe(listener).Store là một phần cốt lõi của kiến trúc Redux và là nền tảng cho việc quản lý trạng thái trong các ứng dụng JavaScript sử dụng Redux.

Bạn nên thực hiện request AJAX ở đâu trong một React component?
Trong một React component, yêu cầu AJAX nên được thực hiện trong phương thức vòng đời componentDidMount khi sử dụng class components, hoặc trong hook useEffect khi sử dụng function components. Điều này đảm bảo rằng yêu cầu AJAX chỉ được thực hiện sau khi component đã được gắn vào DOM, giúp tránh các vấn đề liên quan đến việc cập nhật trạng thái trên một component chưa sẵn sàng.
class MyComponent extends React.Component {
componentDidMount() {
// Thực hiện yêu cầu AJAX ở đây
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => this.setState({ data }));
}
// ...
}
function MyComponent() {
useEffect(() => {
// Thực hiện yêu cầu AJAX ở đây
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => {
// Cập nhật trạng thái hoặc thực hiện hành động khác với dữ liệu
});
}, []); // Mảng rỗng đảm bảo rằng effect chỉ chạy một lần sau khi component mount
// ...
}
Sử dụng useEffect với mảng rỗng làm tham số thứ hai giúp đảm bảo rằng yêu cầu AJAX chỉ được thực hiện một lần sau khi component được mount, tương tự như componentDidMount trong class components.
Làm thế nào để tránh việc cần phải binding trong React?
Trong React, việc binding this trong các phương thức event handler là một bước cần thiết nếu bạn sử dụng ES6 class components và muốn truy cập this trong các phương thức đó. Tuy nhiên, việc này có thể trở nên lặp đi lặp lại và gây rối. Dưới đây là một số cách để tránh việc cần phải binding:
Bạn có thể sử dụng cú pháp class fields trong ES6+ để khai báo các phương thức như arrow functions, điều này tự động bind this cho bạn.
class MyComponent extends React.Component {
handleClick = () => {
console.log(this); // 'this' tự động được bind
}
render() {
return <button onClick={this.handleClick}>Click me</button>;
}
}
Khi truyền event handlers vào JSX, bạn có thể sử dụng arrow functions để tự động bind this mà không cần phải làm điều đó trong constructor.
class MyComponent extends React.Component {
handleClick() {
console.log(this); // 'this' được bind đúng cách
}
render() {
return <button onClick={() => this.handleClick()}>Click me</button>;
}
}
Tuy nhiên, cách này có thể gây ra vấn đề về hiệu suất vì mỗi lần component render, một arrow function mới sẽ được tạo ra.
Nếu bạn sử dụng React 16.8 trở lên, bạn có thể sử dụng functional components với hooks thay vì class components. Trong functional components, không cần phải lo lắng về việc binding this vì không có this trong functional components.
function MyComponent() {
const handleClick = () => {
console.log('Clicked!');
}
return <button onClick={handleClick}>Click me</button>;
}
Nếu bạn vẫn muốn sử dụng class components và không muốn sử dụng arrow functions trong JSX vì lý do hiệu suất, bạn có thể bind this trong constructor của class component.
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
console.log(this); // 'this' được bind đúng cách
}
render() {
return <button onClick={this.handleClick}>Click me</button>;
}
}
Cách này đảm bảo rằng this được bind một lần duy nhất cho mỗi instance của component, giúp tránh việc tạo ra các hàm mới mỗi lần component render.
Sử dụng các cách trên giúp bạn tránh việc cần phải binding trong React, giúp mã nguồn gọn gàng và dễ quản lý hơn.
Children prop trong React là gì?
Trong React, children prop là một prop đặc biệt mà React cung cấp cho mỗi component. Nó chứa nội dung được truyền vào component từ bên ngoài, giúp bạn xây dựng các component có thể tái sử dụng và kết hợp với nhau một cách linh hoạt.
children cho phép bạn truyền nội dung động vào trong component, bao gồm HTML, text, và thậm chí là các component khác.children giúp tạo ra các component có thể tái sử dụng với nội dung khác nhau mà không cần phải tạo ra nhiều component tương tự với những thay đổi nhỏ.children là một phần quan trọng của cơ chế composition trong React, cho phép bạn xây dựng các cấu trúc UI phức tạp từ các component nhỏ và đơn giản.Bạn có thể truyền children vào component như là nội dung giữa các thẻ mở và đóng của component đó trong JSX.
<MyComponent>
<p>This is a child element</p>
</MyComponent>
Trong ví dụ trên, <p>This is a child element</p> là children của MyComponent.
Trong component MyComponent, bạn có thể truy cập children thông qua props.children.
function MyComponent(props) {
return <div>{props.children}</div>;
}
React cung cấp một số API hữu ích trong React.Children để làm việc với children prop, bao gồm React.Children.map, React.Children.forEach, React.Children.count, React.Children.only, và React.Children.toArray. Những API này giúp bạn xử lý children một cách an toàn và hiệu quả khi children có thể là undefined, một object, hoặc một mảng các object.
React.Children.map(props.children, child => {
// Làm gì đó với mỗi child
});
children prop là một công cụ mạnh mẽ trong React, giúp bạn xây dựng các component linh hoạt và tái sử dụng, từ đó tạo ra các ứng dụng có cấu trúc tốt và dễ bảo trì.
Redux là gì?
Redux là một thư viện JavaScript phổ biến dùng để quản lý trạng thái (state) cho các ứng dụng JavaScript. Nó thường được sử dụng với các thư viện giao diện người dùng như React, nhưng có thể được sử dụng với bất kỳ thư viện JavaScript nào khác. Redux cung cấp một cửa hàng trung tâm (central store) cho trạng thái của toàn bộ ứng dụng, giúp quản lý trạng thái trở nên dễ dàng và dự đoán được hơn.

Tuy nhiên, Redux có thể không cần thiết cho các ứng dụng nhỏ hoặc các ứng dụng mà trạng thái có thể được quản lý một cách đơn giản thông qua các công cụ quản lý trạng thái cục bộ của React như Context API và Hooks.
PropTypes trong React để làm gì?
PropTypes trong React được sử dụng để kiểm tra kiểu dữ liệu của props mà một component nhận vào. Nó giúp đảm bảo rằng component đang nhận đúng loại props với đúng định dạng, giúp phát hiện lỗi và ngăn chặn lỗi tiềm ẩn khi phát triển ứng dụng.
string, number, array, object, bool, function, và nhiều kiểu khác.Để sử dụng PropTypes, bạn cần cài đặt gói prop-types và sử dụng nó để xác định kiểu dữ liệu cho props:
import PropTypes from 'prop-types';
function MyComponent({ name, age, friends }) {
// ...
}
MyComponent.propTypes = {
name: PropTypes.string.isRequired,
age: PropTypes.number,
friends: PropTypes.arrayOf(PropTypes.string)
};
Trong ví dụ trên, MyComponent có ba props: name là một chuỗi và bắt buộc phải có, age là một số, và friends là một mảng các chuỗi.
Tóm lại, PropTypes là một công cụ hữu ích trong React giúp kiểm tra kiểu dữ liệu của props, phát hiện lỗi, và cung cấp tài liệu mã nguồn, từ đó giúp tăng cường chất lượng và khả năng bảo trì của ứng dụng.
Mô tả cách hoạt động của kiến trúc Flux?
Flux là một mẫu kiến trúc thực thi luồng dữ liệu một chiều - mục đích cốt lõi của nó là kiểm soát dữ liệu để nhiều component có thể tương tác với dữ liệu đó mà không có nguy cơ ô nhiễm (without risking pollution).
Mẫu Flux là khái niệm chung; nó không dành riêng cho các ứng dụng React, cũng như không bắt buộc phải xây dựng một ứng dụng React. Tuy nhiên, Flux thường được các nhà phát triển React sử dụng vì các React component có tính chất khai báo - UI được hiển thị (View) chỉ đơn giản là một function của state (Store data).

Trong mẫu Flux, Store là cơ quan trung tâm cho tất cả dữ liệu; bất kỳ thay đổi nào đối với dữ liệu phải xảy ra trong Store. Các thay đổi đối với Store data sẽ được truyền đến View qua các event. Sau đó, View sẽ tự cập nhật dựa trên state mới của dữ liệu đã nhận.
Để yêu cầu thay đổi bất kỳ Store data nào, Actions có thể được kích hoạt. Các Action này được kiểm soát bởi một Central Dispatcher;
Các Action sẽ không xảy ra đồng thời, đảm bảo rằng Store chỉ thay đổi dữ liệu một lần cho mỗi Action.
Luồng một chiều nghiêm ngặt của mẫu Flux này thực thi tính ổn định của dữ liệu, giảm các lỗi runtime liên quan đến dữ liệu trong một ứng dụng.
Mô tả cách xử lý các event trong React?
Trong React, việc xử lý các sự kiện (events) được thực hiện thông qua cơ chế tương tự như xử lý sự kiện trong HTML thuần túy, nhưng có một số khác biệt quan trọng và cải tiến nhất định. Dưới đây là cách xử lý các sự kiện trong React:
Trong React, tên của các sự kiện được viết theo cú pháp camelCase thay vì lowercase như trong HTML thuần túy. Ví dụ, thay vì sử dụng "onclick" trong HTML, bạn sẽ sử dụng "onClick" trong JSX của React.
Trong React, bạn truyền một hàm vào thuộc tính của sự kiện để xử lý sự kiện đó. Hàm này có thể được định nghĩa trực tiếp trong JSX hoặc được tham chiếu từ một phương thức của class component.
function MyComponent() {
function handleClick() {
console.log('Button clicked');
}
return (
<button onClick={handleClick}>
Click me
</button>
);
}
class MyComponent extends React.Component {
handleClick() {
console.log('Button clicked');
}
render() {
return (
<button onClick={this.handleClick.bind(this)}>
Click me
</button>
);
}
}
Đôi khi bạn cần truyền tham số cho trình xử lý sự kiện. Trong React, bạn có thể làm điều này bằng cách sử dụng một arrow function hoặc hàm bind.
<button onClick={(e) => this.handleClick(e, someData)}>
Click me
</button>
.bind()<button onClick={this.handleClick.bind(this, someData)}>
Click me
</button>
Để ngăn chặn hành vi mặc định của một sự kiện trong React, bạn có thể gọi preventDefault() trên đối tượng sự kiện được truyền vào hàm xử lý sự kiện.
function handleSubmit(e) {
e.preventDefault();
console.log('Form submitted');
}
// Trong JSX
<form onSubmit={handleSubmit}>
<button type="submit">Submit</button>
</form>
Xử lý sự kiện trong React tương tự như trong HTML thuần túy nhưng với một số cải tiến như cú pháp camelCase cho tên sự kiện, sử dụng hàm để xử lý sự kiện, và khả năng truyền tham số cho trình xử lý sự kiện. Việc sử dụng các hàm xử lý sự kiện giúp tạo ra các ứng dụng React linh hoạt và dễ bảo trì.
Tại sao React sử dụng className thay vì thuộc tính class?
Trong ReactJS, className được sử dụng thay vì thuộc tính class để xác định tên lớp CSS cho các phần tử DOM. Lý do chính cho việc này là class là một từ khóa dành riêng trong JavaScript, và JSX là một cú pháp mở rộng của JavaScript được sử dụng bởi React để mô tả UI.
Khi JSX được biên dịch thành JavaScript, nếu sử dụng từ khóa class, nó có thể gây ra xung đột với việc định nghĩa lớp trong JavaScript (ES6 classes). Để tránh vấn đề này và để JSX có thể hoạt động hài hòa với JavaScript, React sử dụng className để xác định tên lớp CSS.
Ngoài ra, việc sử dụng className giúp phân biệt rõ ràng giữa thuộc tính lớp CSS và khai báo lớp JavaScript, giúp mã nguồn dễ đọc và bảo trì hơn.
Tại sao phải gọi setState thay vì trực tiếp thay đổi state trong React?
Trong React, setState là phương thức được sử dụng để cập nhật state của một component. Việc gọi setState thay vì thay đổi state trực tiếp là quan trọng vì nhiều lý do:
state được coi là bất biến (immutable). Điều này có nghĩa là bạn không nên thay đổi state trực tiếp bằng cách gán giá trị mới cho nó. Thay vào đó, bạn sử dụng setState để thông báo cho React về sự thay đổi và cho phép nó xử lý cập nhật state một cách an toàn.setState kích hoạt một quy trình cập nhật component, bao gồm việc gọi các phương thức lifecycle như shouldComponentUpdate, componentWillUpdate, render, và componentDidUpdate. Khi bạn thay đổi state trực tiếp, quy trình này không được kích hoạt, dẫn đến việc UI không được cập nhật để phản ánh sự thay đổi.setState để tối ưu hóa hiệu suất bằng cách batch (nhóm) các cập nhật state và chỉ áp dụng những thay đổi cần thiết lên DOM. Khi bạn thay đổi state trực tiếp, bạn mất đi khả năng tối ưu hóa này.setState đảm bảo rằng state và UI của component luôn đồng bộ. React sẽ quản lý state và đảm bảo rằng mọi thay đổi đều được phản ánh một cách nhất quán trên UI.Gọi setState là cách chính xác để cập nhật state trong React vì nó đảm bảo rằng quy trình cập nhật component được thực hiện đúng cách, giữ cho state và UI đồng bộ, tối ưu hóa hiệu suất, và duy trì tính bất biến của state. Việc thay đổi state trực tiếp không chỉ là một thực hành không an toàn mà còn có thể dẫn đến các lỗi khó lường và khó debug trong ứng dụng của bạn.
Inline Conditional Expressions trong React là gì?
Inline Conditional Expressions trong React là một kỹ thuật sử dụng các biểu thức điều kiện JavaScript ngay trong JSX để điều khiển việc render của các thành phần. Điều này thường được thực hiện sử dụng toán tử ba ngôi (condition ? trueExpression : falseExpression) hoặc toán tử logic AND (condition && expression) để tạo điều kiện render một cách ngắn gọn và trực tiếp.
Toán tử ba ngôi cho phép bạn thực hiện một kiểm tra điều kiện và chọn một trong hai biểu thức để render dựa trên kết quả của điều kiện đó:
function Welcome(props) {
return (
<div>
{props.isLoggedIn ? <h1>Welcome back!</h1> : <h1>Please sign in.</h1>}
</div>
);
}
Trong ví dụ trên, nếu props.isLoggedIn là true, component sẽ render "Welcome back!", ngược lại sẽ render "Please sign in.".
Toán tử logic AND (&&) thường được sử dụng khi bạn chỉ muốn render một thành phần dựa trên một điều kiện mà không cần đến phần "else":
function Welcome(props) {
return (
<div>
{props.isLoggedIn && <h1>Welcome back!</h1>}
</div>
);
}
Ở đây, "Welcome back!" chỉ được render nếu props.isLoggedIn là true. Nếu props.isLoggedIn là false, biểu thức sau toán tử && sẽ bị bỏ qua và không có gì được render.
Sử dụng Inline Conditional Expressions giúp mã JSX trở nên gọn gàng và dễ đọc hơn, đồng thời cho phép bạn tạo ra các logic render phức tạp mà không cần phải viết các câu lệnh điều kiện rời rạc hoặc sử dụng các phương thức render phụ trợ.
Chức năng của hàm render() trong React là gì?
Hàm render() trong React là một phương thức bắt buộc trong mỗi class component và có chức năng chính là trả về một phần tử React (React element) để mô tả những gì sẽ được hiển thị trên giao diện người dùng (UI). Nói cách khác, hàm render() xác định cấu trúc của giao diện người dùng bằng cách trả về các thành phần React, JSX, hoặc các loại nút DOM và component khác.
render():render() mỗi khi trạng thái (state) hoặc props của component thay đổi, dẫn đến việc cập nhật giao diện người dùng.render() phải là một hàm "pure", nghĩa là nó không thay đổi trạng thái của component, không tương tác trực tiếp với trình duyệt, và trả về cùng một kết quả với cùng một tập hợp các đầu vào.render() có thể trả về một phần tử React, một mảng các phần tử, chuỗi, số, hoặc null/false để không render gì cả.render():class MyComponent extends React.Component {
render() {
return (
<div>
Hello, {this.props.name}!
</div>
);
}
}
Trong ví dụ trên, hàm render() trả về một phần tử div chứa một chuỗi chào mừng, sử dụng giá trị từ props của component.
Tóm lại, hàm render() là một phần không thể thiếu trong mỗi class component của React, đóng vai trò quan trọng trong việc xác định cách giao diện người dùng được cấu trúc và hiển thị.
Ba dấu chấm ... trong React để làm gì?
Trong React, ba dấu chấm (...), còn được gọi là spread operator, là một cú pháp ES6 được sử dụng để "trải" các phần tử của một mảng hoặc các thuộc tính của một đối tượng ra thành các phần tử hoặc thuộc tính riêng lẻ. Dưới đây là một số cách sử dụng spread operator trong React:
Spread operator có thể được sử dụng để truyền toàn bộ props của một đối tượng đến một component một cách dễ dàng.
const myProps = { name: 'John', age: 30 };
<MyComponent {...myProps} />
Trong ví dụ trên, tất cả các thuộc tính trong myProps sẽ được truyền như là props đến MyComponent.
Spread operator cũng có thể được sử dụng để kết hợp các đối tượng, tạo ra một đối tượng mới chứa tất cả các thuộc tính từ các đối tượng ban đầu.
const obj1 = { a: 1, b: 2 };
const obj2 = { c: 3, d: 4 };
const combinedObj = { ...obj1, ...obj2 };
combinedObj sẽ là { a: 1, b: 2, c: 3, d: 4 }.
Spread operator cũng được sử dụng để tạo bản sao của mảng.
const originalArray = [1, 2, 3];
const copiedArray = [...originalArray];
copiedArray sẽ là một bản sao của originalArray.
Spread operator cho phép bạn thêm phần tử vào mảng một cách dễ dàng.
const someArray = [1, 2, 3];
const extendedArray = [...someArray, 4, 5];
extendedArray sẽ là ``.
Spread operator có thể được sử dụng để truyền một mảng các giá trị vào một hàm như là các đối số riêng lẻ.
function myFunction(x, y, z) { /* ... */ }
const args = [0, 1, 2];
myFunction(...args);
Trong ví dụ trên, myFunction được gọi với các đối số 0, 1, và 2.
Tóm lại, spread operator là một công cụ hữu ích trong React và JavaScript nói chung, giúp việc làm việc với mảng và đối tượng trở nên linh hoạt và dễ dàng hơn.
React có re-render tất cả các components và sub components mỗi khi gọi setState không?
Không, React không re-render tất cả các components và sub-components mỗi khi setState được gọi. React sử dụng một quá trình gọi là reconciliation để xác định những phần nào của component tree cần được cập nhật dựa trên sự thay đổi của state hoặc props.
Khi setState được gọi, React sẽ lên lịch một cập nhật và sau đó thực hiện các bước sau:
render: React gọi phương thức render của component mà setState được gọi, cũng như của các sub-components của nó, để tạo ra một cây React elements mới.componentDidUpdate trên các component đã được cập nhật.Do đó, không phải tất cả các components và sub-components đều được re-render. Chỉ những components có sự thay đổi trong output của phương thức render (do thay đổi state hoặc props) mới được React cập nhật. Điều này giúp tối ưu hóa hiệu suất và tránh việc re-render không cần thiết.
React hoạt động như thế nào?
React là một thư viện JavaScript được sử dụng để xây dựng giao diện người dùng (UI) đặc biệt là các ứng dụng một trang (SPA - Single Page Applications). React được phát triển bởi Facebook và hiện tại là một trong những thư viện front-end phổ biến nhất. Dưới đây là cách React hoạt động:
React sử dụng kiến trúc dựa trên component, nghĩa là UI được chia thành các phần nhỏ, độc lập gọi là components. Mỗi component có thể quản lý trạng thái (state) của nó và được tái sử dụng trong ứng dụng. Điều này giúp việc phát triển ứng dụng trở nên dễ dàng và hiệu quả hơn.
React sử dụng JSX, một cú pháp mở rộng cho JavaScript, cho phép viết cấu trúc UI giống như HTML trong mã JavaScript. JSX giúp mã nguồn dễ đọc và viết hơn, đồng thời cho phép React hiển thị thông tin từ mã JavaScript dễ dàng hơn thông qua cú pháp giống như template.
React sử dụng Virtual DOM để tối ưu hóa hiệu suất bằng cách giảm thiểu số lượng cập nhật DOM thực tế. Khi trạng thái của một component thay đổi, React sẽ tạo ra một Virtual DOM tree mới và so sánh nó với phiên bản trước đó để xác định những thay đổi cần được thực hiện trên DOM thực tế. Điều này giúp tăng tốc độ và hiệu suất của ứng dụng.
React thực hiện một chiều dữ liệu ràng buộc (one-way data binding), nghĩa là dữ liệu trong ứng dụng chỉ di chuyển theo một hướng từ parent components xuống child components thông qua props. Điều này giúp kiểm soát và theo dõi dòng dữ liệu trong ứng dụng dễ dàng hơn, giảm thiểu lỗi và tăng khả năng bảo trì.
React Hooks là một tính năng được giới thiệu trong React 16.8, cho phép sử dụng trạng thái và các tính năng khác của React mà không cần viết dưới dạng class. Hooks giúp viết các functional components mạnh mẽ hơn với ít code hơn và dễ dàng tái sử dụng logic giữa các components.
React Fiber là một cơ chế mới cho thuật toán reconciler của React, giúp cải thiện khả năng xử lý các tác vụ không đồng bộ, tối ưu hóa việc sử dụng tài nguyên và quản lý ưu tiên cập nhật UI. Fiber giúp React có thể thực hiện "time slicing" - chia nhỏ công việc và phân phối nó qua nhiều khung hình, giúp ứng dụng mượt mà hơn.
React hoạt động bằng cách kết hợp các tính năng này để tạo ra một thư viện mạnh mẽ, linh hoạt và hiệu quả cho việc phát triển giao diện người dùng.
Làm thế nào để truyền một parameter vào một event handler hoặc callback?
Để truyền một parameter vào một event handler hoặc callback trong React, bạn có thể sử dụng một arrow function hoặc function bên trong JSX. Điều này cho phép bạn gửi thêm dữ liệu vào hàm xử lý sự kiện khi nó được gọi.
Bạn có thể truyền parameter trực tiếp vào một arrow function bên trong JSX:
<button onClick={(e) => this.handleClick(e, parameter)}>Click me</button>
Trong ví dụ trên, handleClick là hàm xử lý sự kiện, e là đối tượng sự kiện, và parameter là dữ liệu bạn muốn truyền vào hàm.
Nếu bạn đang sử dụng một class component, bạn có thể bind hàm xử lý sự kiện trong constructor và truyền parameter:
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
handleClick(parameter, e) {
// Xử lý sự kiện ở đây
}
render() {
return (
<button onClick={(e) => this.handleClick(parameter, e)}>Click me</button>
);
}
Trong ví dụ trên, handleClick được bind trong constructor để đảm bảo this được set đúng cách, và parameter được truyền vào khi gọi hàm.
Một cách khác là sử dụng function currying, nghĩa là tạo một hàm trả về một hàm khác:
handleClick = (parameter) => (e) => {
// Xử lý sự kiện ở đây
}
render() {
return (
<button onClick={this.handleClick(parameter)}>Click me</button>
);
}
Trong ví dụ trên, handleClick trả về một arrow function mới khi nó được gọi với parameter. Arrow function này sau đó sẽ được sử dụng như một event handler và có quyền truy cập vào parameter và đối tượng sự kiện e.
Sử dụng các phương pháp trên, bạn có thể dễ dàng truyền parameters vào event handlers hoặc callbacks trong React.
Single Page Applications là gì?
Single Page Applications (SPA) là các ứng dụng web mà khi sử dụng, trình duyệt chỉ cần tải một trang duy nhất từ máy chủ. Thay vì tải lại toàn bộ trang web khi người dùng tương tác với ứng dụng, SPA sử dụng JavaScript để tương tác với trang hiện tại và cập nhật nội dung mới.
Điều này có nghĩa là các tính năng và dữ liệu mới có thể được tải về và hiển thị trên cùng một trang mà không cần tải lại trang hoặc chuyển hướng sang trang khác. Điều này tạo ra trải nghiệm người dùng liền mạch và nhanh chóng hơn, vì người dùng không phải chờ đợi để tải lại toàn bộ trang web.
SPA thường sử dụng các framework JavaScript như React, Angular hoặc Vue.js để xây dựng các ứng dụng phức tạp. Các framework này cung cấp các công cụ và thư viện hỗ trợ cho việc quản lý trạng thái ứng dụng, định tuyến và tải dữ liệu từ máy chủ.
Một ưu điểm của SPA là khả năng tạo ra giao diện người dùng tương tác mượt mà và có trải nghiệm tương tự như ứng dụng máy tính. Tuy nhiên, việc tải toàn bộ mã và tài nguyên cần thiết cho ứng dụng ban đầu có thể làm cho thời gian tải ban đầu lâu hơn so với các ứng dụng truyền thống.
Với sự phát triển của công nghệ web, SPA đã trở thành một phong cách phát triển phổ biến và được sử dụng rộng rãi trong việc xây dựng các ứng dụng web hiện đại.
Làm thế nào để áp dụng validation trên Props trong React?
Trong ReactJS, việc áp dụng validation trên props giúp đảm bảo rằng các component nhận đúng loại dữ liệu và đúng định dạng dữ liệu từ props, từ đó giúp ứng dụng hoạt động chính xác và an toàn hơn. React cung cấp một cách để thực hiện điều này thông qua thư viện prop-types.
prop-types để Validate Propsprop-types: Đầu tiên, bạn cần cài đặt thư viện prop-types nếu nó chưa được cài đặt trong dự án của bạn.npm install prop-types
prop-types để xác định rõ ràng loại dữ liệu và các ràng buộc khác cho props của component.import React from 'react';
import PropTypes from 'prop-types';
class MyComponent extends React.Component {
render() {
// Sử dụng props ở đây
}
}
MyComponent.propTypes = {
name: PropTypes.string.isRequired, // name phải là một string và là bắt buộc
age: PropTypes.number, // age phải là một số
onLogin: PropTypes.func, // onLogin phải là một hàm
isStudent: PropTypes.bool, // isStudent phải là một giá trị boolean
address: PropTypes.shape({ // address phải là một đối tượng với cấu trúc xác định
street: PropTypes.string,
city: PropTypes.string
})
};
Trong ví dụ trên, MyComponent có một số props với các loại dữ liệu và ràng buộc cụ thể được xác định thông qua prop-types.
prop-types cũng có thể coi như một hình thức tài liệu tự động cho các component của bạn, giúp các nhà phát triển khác trong dự án hiểu được cách sử dụng component.Việc áp dụng validation trên props thông qua prop-types là một phương pháp hay được khuyến khích sử dụng trong ReactJS để tăng cường tính rõ ràng và độ tin cậy của ứng dụng.
Flux là gì?
Flux là một kiến trúc ứng dụng được phát triển bởi Facebook để xây dựng các ứng dụng giao diện người dùng (UI) phía client. Flux được thiết kế để giải quyết một số vấn đề với kiến trúc MVC (Model-View-Controller) truyền thống, đặc biệt là về việc quản lý dữ liệu và luồng dữ liệu trong các ứng dụng lớn và phức tạp.
Flux bao gồm bốn thành phần chính:
Flux áp dụng một mô hình luồng dữ liệu một chiều (unidirectional data flow), nghĩa là dữ liệu trong ứng dụng di chuyển theo một hướng rõ ràng từ Actions đến Dispatcher, sau đó đến Stores và cuối cùng đến Views. Mô hình này giúp quản lý trạng thái ứng dụng trở nên dễ dàng và dự đoán được hơn, đồng thời giảm thiểu sự phức tạp khi ứng dụng phát triển.
Flux không phải là một thư viện hoặc framework cụ thể mà là một kiến trúc, và có thể được triển khai bằng nhiều cách khác nhau tùy thuộc vào yêu cầu cụ thể của ứng dụng.
Sự khác biệt giữa Presentational component và Container component trong React là gì?
Trong React, sự phân biệt giữa Presentational component và Container component là một mô hình thiết kế giúp tách biệt trách nhiệm giữa việc quản lý dữ liệu và việc hiển thị giao diện người dùng. Mô hình này giúp tạo ra các ứng dụng dễ bảo trì, mở rộng và tái sử dụng.
Tóm lại, việc phân biệt giữa Presentational và Container components trong React giúp tạo ra một cấu trúc ứng dụng rõ ràng, dễ quản lý và bảo trì, đồng thời tăng cường khả năng tái sử dụng của code.
Error Boundary được xử lý thế nào trong React?
Trong React, Error Boundary là một cơ chế cho phép bạn bắt và xử lý các lỗi JavaScript trong các phần của cây component, ngăn chặn lỗi từ việc "lan" ra toàn bộ ứng dụng. Error Boundary được xử lý bằng cách sử dụng các class component đặc biệt có thể bắt các lỗi xảy ra trong quá trình render, trong các phương thức lifecycle, và trong các constructor của toàn bộ cây component dưới chúng.
Để tạo một Error Boundary, bạn cần định nghĩa một class component và sử dụng ít nhất một trong hai phương thức lifecycle sau:
static getDerivedStateFromError(error): Phương thức này được gọi khi một lỗi được ném ra từ một component con trong quá trình render. Nó trả về một đối tượng state mới dựa trên lỗi nhận được, cho phép bạn hiển thị một UI dự phòng.componentDidCatch(error, info): Phương thức này được gọi sau khi lỗi xảy ra. Nó cho phép bạn ghi log lỗi và thu thập thông tin về lỗi, như stack trace.class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
// Cập nhật state để component tiếp theo có thể render UI dự phòng
return { hasError: true };
}
componentDidCatch(error, info) {
// Bạn cũng có thể log lỗi ra console hoặc gửi lỗi đến một dịch vụ báo cáo lỗi
console.error("ErrorBoundary caught an error", error, info);
}
render() {
if (this.state.hasError) {
// Bạn có thể render bất kỳ UI dự phòng nào
return <h1>Something went wrong.</h1>;
}
return this.props.children;
}
}
Bạn có thể sử dụng Error Boundary bằng cách bọc nó quanh các component mà bạn muốn bảo vệ khỏi lỗi. Khi một lỗi xảy ra trong một component con của Error Boundary, UI dự phòng sẽ được render thay thế cho component gây ra lỗi.
<ErrorBoundary>
<MyComponent />
</ErrorBoundary>
try/catch trong event handlers)setTimeout hoặc requestAnimationFrame callbacks)Error Boundary là một tính năng quan trọng trong React giúp tăng cường độ tin cậy của ứng dụng bằng cách xử lý các lỗi không mong muốn một cách ân toàn và hiệu quả.
Context API trong ReactJS là gì?
Context API trong ReactJS là một cơ chế cho phép bạn truyền dữ liệu qua lại giữa các component mà không cần phải sử dụng props một cách thủ công từng cấp một. Nói cách khác, Context API cung cấp một cách để chia sẻ giá trị (như dữ liệu người dùng, theme, ngôn ngữ) giữa các component mà không cần phải truyền props ở mỗi cấp của cây component.
Context API được thiết kế để chia sẻ dữ liệu mà có thể được coi là "global" cho một cây của các component React, giúp giảm bớt sự phức tạp khi truyền dữ liệu giữa các component sâu trong cây component. Điều này đặc biệt hữu ích trong các ứng dụng lớn, nơi việc truyền props có thể trở nên cồng kềnh và khó quản lý.
Để sử dụng Context API, bạn sẽ tạo một Context bằng cách sử dụng React.createContext() và sau đó sử dụng Context.Provider để bao bọc cây component, cung cấp một giá trị cho Context đó. Các component con có thể truy cập giá trị Context này bằng cách sử dụng Context.Consumer hoặc Hook useContext().
Context API giúp quản lý trạng thái toàn cục của ứng dụng một cách dễ dàng hơn và là một phần của React từ phiên bản 16.3 trở đi.
Lifting State Up trong ReactJS là gì?
Lifting State Up trong ReactJS là một kỹ thuật được sử dụng để chia sẻ trạng thái giữa nhiều thành phần. Thay vì mỗi thành phần có trạng thái cục bộ riêng của mình, kỹ thuật này liên quan đến việc di chuyển quản lý trạng thái từ các thành phần con lên một tổ tiên chung (thành phần cha). Theo cách này, trạng thái trở thành "nguồn sự thật" cho các thành phần con, và chúng có thể truy cập và cập nhật nó thông qua props.
Ví dụ, xem xét một ứng dụng React với một thành phần gọi là máy tính có hai đầu vào. Mỗi đầu vào có trạng thái cục bộ của riêng mình, và chúng cần phản ánh cùng một dữ liệu thay đổi. Nếu một đầu vào thay đổi, đầu vào khác cũng nên phản ánh sự thay đổi này. Tuy nhiên, nếu mỗi đầu vào duy trì trạng thái cục bộ của mình, chúng không thể ảnh hưởng trực tiếp đến trạng thái của nhau. Đây là nơi "Lifting State Up" trở nên hữu ích. Bằng cách di chuyển trạng thái lên tổ tiên chung gần nhất (thành phần máy tính), chúng ta có thể đảm bảo rằng cả hai đầu vào đều đồng bộ.
"Lifting State Up" quan trọng vì nó giúp duy trì sự nhất quán trong dữ liệu hiển thị bởi các thành phần khác nhau. Nó đảm bảo rằng việc thay đổi dữ liệu trong một thành phần dẫn đến việc cập nhật cùng một dữ liệu trong tất cả các thành phần khác phụ thuộc vào nó. Điều này đặc biệt quan trọng trong các ứng dụng phức tạp, nơi nhiều thành phần có thể cần chia sẻ và hiển thị cùng một trạng thái.
Khi trạng thái được "nâng lên", nó trở thành "nguồn sự thật" cho các thành phần con. Các thành phần này nhận trạng thái dưới dạng props và chỉ có thể cập nhật nó bằng cách gọi một hàm được cung cấp bởi thành phần cha. Điều này đảm bảo rằng trạng thái luôn được giữ nhất quán và cập nhật.
Quá trình Reconciliation trong ReactJS là gì?
Quá trình Reconciliation trong ReactJS là một cơ chế mà React sử dụng để cập nhật hiệu quả DOM (Document Object Model) của trình duyệt và đảm bảo hiệu suất tối ưu. Khi các thành phần React được render, chúng tạo ra một cấu trúc giống như cây gọi là Virtual DOM (VDOM), là một biểu diễn nhẹ của DOM thực tế. Mỗi khi có sự thay đổi trong trạng thái (state) hoặc props của thành phần, React thực hiện quá trình Reconciliation để so sánh VDOM trước và sau khi thay đổi, và áp dụng chỉ những cập nhật cần thiết lên DOM thực tế.
Quá trình này bao gồm các bước chính sau:
Quá trình Reconciliation không chỉ giúp tối ưu hóa hiệu suất bằng cách giảm thiểu số lượng thao tác DOM cần thiết mà còn giúp cung cấp trải nghiệm người dùng mượt mà bằng cách đảm bảo rằng giao diện người dùng luôn phản ánh trạng thái mới nhất của ứng dụng. Để tăng cường hiệu quả của quá trình Reconciliation, React khuyến khích sử dụng thuộc tính key cho mỗi element trong một mảng được render bởi một thành phần, giúp React xác định chính xác các element nào đã được thêm, loại bỏ, hoặc di chuyển trong quá trình Reconciliation.
Components Composition trong React là gì?
Components Composition trong React là một kỹ thuật phát triển dựa trên mô hình thành phần gốc của React, nơi chúng ta xây dựng các thành phần từ các thành phần khác bằng cách sử dụng props children. Kỹ thuật này cho phép tạo ra các thành phần có thể tái sử dụng và mở rộng, giúp loại bỏ mã trùng lặp và làm cho ứng dụng dễ bảo trì hơn khi cần thêm tính năng mới mà không cần phải sửa đổi nhiều tệp.
Thành phần ghép là một khái niệm cốt lõi trong ReactJS, một thư viện JavaScript phổ biến để xây dựng giao diện người dùng. Trong ReactJS, các thành phần là các khối xây dựng của ứng dụng, và chúng có thể được kết hợp và tái sử dụng để tạo ra các thành phần phức tạp hơn. Thành phần ghép cho phép các nhà phát triển xây dựng các ứng dụng có cấu trúc mô-đun, có khả năng mở rộng và dễ bảo trì. Bằng cách chia ứng dụng thành các thành phần nhỏ hơn, các nhà phát triển có thể cô lập và gỡ lỗi vấn đề dễ dàng hơn, tái sử dụng mã ở các phần khác nhau của ứng dụng và thực hiện thay đổi nhanh chóng mà không ảnh hưởng đến các phần khác của ứng dụng.
Thành phần ghép trong ReactJS được thực hiện thông qua một số cơ chế khác nhau, chẳng hạn như sử dụng props để truyền dữ liệu giữa các thành phần và sử dụng các thành phần bậc cao (higher-order components) để bao bọc và nâng cao các thành phần hiện có. Ngoài ra, ReactJS cũng hỗ trợ một khái niệm được gọi là "render props", cho phép các thành phần nhận một hàm như một prop, mà sau đó chúng có thể sử dụng để render đầu ra của mình.
Có một số lợi ích khi sử dụng thành phần ghép trong ReactJS:
Như vậy, thành phần ghép là một khái niệm cốt lõi trong ReactJS và là một công cụ mạnh mẽ để xây dựng giao diện người dùng mô-đun, có thể tái sử dụng và dễ bảo trì.
Khi nào nên sử dụng useState so với useReducer trong React?
Bạn nên sử dụng useState khi bạn đang quản lý các phần tử trạng thái độc lập không phụ thuộc lẫn nhau. useState là một hook đơn giản cho phép bạn quản lý một biến trạng thái duy nhất. Nó thích hợp cho các trạng thái đơn giản hoặc khi logic kinh doanh không phức tạp.
Ngược lại, useReducer nên được sử dụng khi trạng thái của bạn phức tạp hơn hoặc khi các phần tử trạng thái có sự phụ thuộc lẫn nhau. useReducer cho phép bạn quản lý nhiều hành động khác nhau trong một hàm reducer duy nhất thay vì viết các hàm cập nhật riêng biệt cho mỗi hành động. Điều này làm cho useReducer trở nên lý tưởng cho các ứng dụng lớn hơn với độ phức tạp cao hơn khi quản lý các thay đổi trạng thái giữa các thành phần.
Nếu bạn có nhiều biến trạng thái và muốn có quy tắc cụ thể cho cách cập nhật được xử lý, useReducer sẽ là lựa chọn phù hợp. Nó cũng hữu ích khi trạng thái của bạn bao gồm các đối tượng hoặc mảng và đặc biệt nếu chúng chứa các trạng thái liên quan đến nhau.
Tóm lại, sử dụng useState cho các trạng thái đơn giản và độc lập, và chuyển sang useReducer khi bạn cần quản lý trạng thái phức tạp hơn hoặc khi trạng thái cần được cập nhật dựa trên các trạng thái khác hoặc khi bạn muốn cấu trúc mã nguồn của mình có thêm nhiều tổ chức.
Sự khác biệt giữa Component và Container trong Redux là gì?
Trong Redux, sự khác biệt chính giữa Component và Container liên quan đến cách chúng tương tác với Redux store và vai trò của chúng trong kiến trúc ứng dụng.
Tóm lại, Component trong Redux chủ yếu tập trung vào việc hiển thị dữ liệu và cách thức giao diện người dùng trông như thế nào, trong khi Container tập trung vào việc quản lý trạng thái và logic ứng dụng, bao gồm việc tương tác với Redux store để lấy và cập nhật dữ liệu.
Bạn sẽ sử dụng flushSync trong ReactJS khi nào?
Bạn sẽ sử dụng flushSync trong ReactJS trong các trường hợp cụ thể khi bạn cần cập nhật giao diện người dùng (UI) ngay lập tức và không muốn chờ đợi cho đến khi React cập nhật DOM theo cơ chế batch mặc định của nó. flushSync là một hàm được giới thiệu trong React 18, cho phép bạn buộc React phải xử lý các cập nhật bên trong callback của nó một cách đồng bộ trước khi tiếp tục với phần còn lại của vòng lặp sự kiện JavaScript.
Dưới đây là một số trường hợp cụ thể mà việc sử dụng flushSync có thể hữu ích:
Tuy nhiên, cần lưu ý rằng việc sử dụng flushSync có thể ảnh hưởng đến hiệu suất nếu sử dụng quá thường xuyên, vì nó bỏ qua cơ chế batch mặc định của React, có thể dẫn đến việc tăng số lần re-render không cần thiết. Do đó, flushSync nên được sử dụng một cách cẩn thận và chỉ trong những trường hợp thực sự cần thiết.
Cách sử dụng React.memo() như thế nào?
React.memo() là một higher order component (HOC) được sử dụng để ngăn chặn việc render lại không cần thiết của component. Nó cho phép bạn tối ưu hóa hiệu suất của các functional component bằng cách ghi nhớ kết quả render cuối cùng và chỉ re-render khi props thay đổi.
Để sử dụng React.memo(), bạn bọc component của mình với React.memo() như sau:
const MyComponent = React.memo(function MyComponent(props) {
// Component sẽ chỉ re-render nếu props thay đổi
});
Khi một component được bọc bởi React.memo(), React sẽ kiểm tra xem props của component có thay đổi giữa các lần render hay không. Nếu không có sự thay đổi nào, React sẽ sử dụng lại kết quả render trước đó thay vì tạo ra một kết quả mới.
Trong trường hợp bạn muốn tùy chỉnh việc so sánh props, bạn có thể truyền vào một hàm so sánh tùy chỉnh như tham số thứ hai cho React.memo():
function areEqual(prevProps, nextProps) {
// Trả về true nếu props trước và sau không thay đổi
// Trả về false nếu props có sự thay đổi và cần re-render
}
export default React.memo(MyComponent, areEqual);
Hãy nhớ rằng React.memo() chỉ nên được sử dụng khi bạn xác định được rằng việc re-render là không cần thiết và nó có thể cải thiện hiệu suất của ứng dụng. Tránh sử dụng React.memo() một cách không cần thiết vì nó có thể dẫn đến việc tăng thời gian CPU và giảm hiệu suất nếu việc so sánh props quá phức tạp hoặc không cần thiết.
Một custom hook trong React có thể trả về JSX không?
Một custom hook trong React không nên trả về JSX. Custom hook được thiết kế để tái sử dụng logic, không phải để xử lý UI hay trả về các phần tử giao diện. Việc bao gồm JSX trong một custom hook có thể dẫn đến các vấn đề về hiệu suất và làm cho logic khó tái sử dụng trong các bối cảnh khác nhau.
Mặc dù không có quy định cứng rắn cấm việc trả về JSX từ một custom hook, nhưng điều này được coi là một anti-pattern. Custom hook nên tập trung vào việc cung cấp logic và trạng thái, và để cho các component sử dụng hook đó quyết định cách hiển thị UI dựa trên dữ liệu hoặc trạng thái được trả về từ hook.
Ví dụ, thay vì trả về JSX, một custom hook có thể trả về dữ liệu hoặc trạng thái và các hàm để tương tác với dữ liệu đó. Sau đó, component sử dụng hook có thể sử dụng dữ liệu và hàm được trả về để tạo ra JSX phù hợp.
Tóm lại, mặc dù kỹ thuật lập trình trong React không cấm việc một custom hook trả về JSX, nhưng theo các nguyên tắc và phong cách lập trình idiomatic trong React, custom hook nên được sử dụng để chia sẻ logic, không phải để chia sẻ phần tử giao diện.
Sự khác biệt giữa Element và Component trong React là gì?
Trong React, Element và Component là hai khái niệm cơ bản nhưng khác biệt.
Element:
Component:
render(). Hoặc, trong trường hợp đơn giản, nó có thể được định nghĩa như một hàm.Tóm lại, Element là một đối tượng đơn giản mô tả những gì bạn muốn hiển thị và là đơn vị cấu trúc nhỏ nhất trong React, trong khi Component là một khối xây dựng có thể tái sử dụng, có thể chứa các Element và logic bên trong. Component là cách bạn tạo ra các phần tương tác và phức tạp của UI bằng cách kết hợp các Element với nhau.
Làm thế nào để truyền dữ liệu từ component con sang component cha trong React?
Để truyền dữ liệu từ component con sang component cha trong React, bạn thường sử dụng một hàm callback được định nghĩa trong component cha và sau đó truyền hàm này xuống component con dưới dạng props. Khi cần truyền dữ liệu từ con lên cha, component con sẽ gọi hàm callback này và truyền dữ liệu làm đối số.
Cụ thể, bạn có thể thực hiện các bước sau:
Ví dụ, nếu bạn có một hàm handleData trong component cha và muốn truyền dữ liệu từ component con, bạn có thể làm như sau:
// Trong component cha
class ParentComponent extends React.Component {
handleData = (dataFromChild) => {
// Xử lý dữ liệu nhận được từ con ở đây
}
render() {
return <ChildComponent sendData={this.handleData} />;
}
}
// Trong component con
class ChildComponent extends React.Component {
someFunction = () => {
const data = 'Dữ liệu cần truyền';
this.props.sendData(data);
}
render() {
return <button onClick={this.someFunction}>Gửi Dữ liệu</button>;
}
}
Trong ví dụ trên, khi sự kiện click xảy ra trong ChildComponent, hàm someFunction sẽ được gọi và dữ liệu sẽ được truyền lên ParentComponent thông qua hàm handleData.
Làm thế nào để truy cập vào nút DOM trong một React component?
ReactDOM cung cấp cho bạn phương thức ReactDOM.findDOMNode(param) để tìm đối tượng Node tương ứng với tham số của phương thức.
Bên trong Class Component nếu bạn gọi phương thức ReactDOM.findDOMNode(this), nó sẽ trả về cho bạn nút gốc (Root Node) của mô hình DOM. Ví dụ:
// File: findDOMNode-example.jsx
class Fruits extends React.Component {
doFind() {
// Find root Node of this Component
var node = ReactDOM.findDOMNode(this);
node.style.border = "1px solid red";
}
render() {
return (
<ul>
<li>Apple</li>
<li>Apricot</li>
<li>Banana</li>
<li>
<button onClick={() => this.doFind()}>Find Root Node</button>
</li>
</ul>
);
}
}
// Render
ReactDOM.render(<Fruits />, document.getElementById("fruits1"));
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>ReactJS findDOMNode()</title>
<script src="https://unpkg.com/react@16.4.2/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@16.4.2/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/babel-standalone@6.26.0/babel.min.js"></script>
<style>
#fruits1 {
border: 1px solid blue;
padding: 5px;
margin-top: 20px;
}
</style>
</head>
<body>
<h3>Example: findDOMNode(this)</h3>
<a href="">Reset</a>
<div id="fruits1"></div>
<script src="findDOMNode-example.jsx" type="text/babel"></script>
</body>
</html>
Kết quả:

Sự khác biệt giữa Flow và PropTypes trong React là gì?
Flow và PropTypes trong React đều là công cụ được sử dụng để kiểm tra kiểu dữ liệu của props trong các component React, nhưng chúng có những khác biệt cơ bản về cách thức hoạt động và mục đích sử dụng:
Tóm lại, Flow và PropTypes đều hữu ích trong việc kiểm tra kiểu dữ liệu trong React, nhưng chúng phục vụ cho các mục đích và cách thức hoạt động khác nhau. Flow cung cấp kiểm tra kiểu dữ liệu tĩnh mạnh mẽ cho toàn bộ mã nguồn, trong khi PropTypes cung cấp một cách đơn giản để kiểm tra kiểu dữ liệu của props tại thời điểm chạy.
Điều gì xảy ra khi bạn gọi setState trong React?
Khi bạn gọi setState trong React, bạn yêu cầu React cập nhật trạng thái (state) của một component và sau đó tái render component đó cùng với các component con của nó (nếu cần). Dưới đây là quy trình chi tiết về những gì xảy ra:
setState nhận vào một đối tượng hoặc một hàm. Đối tượng này chứa phần của trạng thái mà bạn muốn cập nhật, hoặc hàm này nhận trạng thái hiện tại và props làm đối số và trả về một đối tượng trạng thái mới. React sau đó sẽ lên lịch cập nhật trạng thái của component với thông tin mới.
renderSau khi trạng thái được cập nhật, React sẽ gọi phương thức render của component để xác định cách giao diện người dùng nên thay đổi dựa trên trạng thái mới. Phương thức render trả về một cây React element (thường được tạo từ JSX).
React sau đó sẽ so sánh cây React element mới với phiên bản trước đó của cây đó (được lưu trữ trong Virtual DOM). Quá trình này được gọi là "diffing". React xác định những phần nào của giao diện người dùng cần thay đổi dựa trên sự khác biệt giữa hai phiên bản của cây.
Sau khi xác định những thay đổi cần thiết, React sẽ cập nhật DOM thực tế một cách hiệu quả. React chỉ áp dụng những thay đổi tối thiểu cần thiết để đưa DOM thực tế vào trạng thái mới, giúp tối ưu hóa hiệu suất.
Nếu component sử dụng các phương thức lifecycle như componentDidUpdate, React sẽ gọi các phương thức này sau khi component và các component con của nó đã được tái render và cập nhật trên DOM. Điều này cho phép bạn thực hiện bất kỳ hành động nào sau khi cập nhật, như yêu cầu dữ liệu từ một API.
setState là một hành động không đồng bộ. React có thể trì hoãn việc thực thi setState để tối ưu hóa hiệu suất bằng cách nhóm nhiều cập nhật lại với nhau.setState do tính chất không đồng bộ của nó. Thay vào đó, sử dụng callback trong setState hoặc lifecycle hooks để làm việc với trạng thái sau khi nó được cập nhật.Quá trình này giúp đảm bảo rằng giao diện người dùng luôn phản ánh trạng thái hiện tại của ứng dụng một cách chính xác và hiệu quả.
Trong React, tại sao cần liên kết các event handler với this?
Trong React, việc liên kết các event handler với this là quan trọng vì nó đảm bảo rằng trong phương thức xử lý sự kiện, từ khóa this sẽ tham chiếu đúng đến instance của component. Điều này là cần thiết do cách this hoạt động trong JavaScript và cách React thiết lập các sự kiện.
this:this: Trong JavaScript, phạm vi của từ khóa this phụ thuộc vào cách mà một hàm được gọi chứ không phải là cách nó được viết hoặc khai báo. Điều này có nghĩa là khi bạn truyền một phương thức của component như một event handler, mà không liên kết this, this sẽ không tham chiếu đến component khi phương thức được gọi như một phản ứng với sự kiện.state hoặc props: Khi this không được liên kết đúng cách trong event handler, bạn sẽ không thể truy cập this.state hoặc this.props bên trong phương thức đó, vì this sẽ là undefined hoặc tham chiếu đến một đối tượng không mong muốn.setState: Tương tự, bạn cũng sẽ không thể gọi this.setState để cập nhật trạng thái của component, vì this không tham chiếu đến instance của component.this:Sử dụng Arrow Functions trong JSX:
Arrow functions không có this riêng, chúng kế thừa this từ phạm vi bao quanh. Khi sử dụng arrow function để định nghĩa event handler ngay trong JSX, this sẽ tự động tham chiếu đúng đến component.
<button onClick={(e) => this.handleClick(e)}>Click me</button>
Liên kết trong Constructor:
Một cách khác là liên kết this trong constructor của class component. Điều này đảm bảo rằng this sẽ tham chiếu đúng mỗi khi phương thức được gọi.
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
Sử dụng Class Fields với Arrow Functions:
Bạn cũng có thể định nghĩa event handler như một class field sử dụng arrow function. Cách này giúp this tự động được liên kết đúng.
handleClick = (e) => {
console.log(this.props);
}
Việc liên kết this đúng cách trong các event handler là một bước quan trọng để đảm bảo rằng ứng dụng React của bạn hoạt động như mong đợi, cho phép bạn truy cập và quản lý state, props, và gọi các phương thức khác của component một cách hiệu quả.
Làm thế nào để thêm các attributes vào các React components một cách có điều kiện?
Trong React, việc thêm các attributes vào components một cách có điều kiện có thể được thực hiện thông qua việc sử dụng JavaScript expressions trong JSX. Dưới đây là một số cách phổ biến để thực hiện điều này:
Bạn có thể sử dụng toán tử ba ngôi (condition ? true : false) để thêm attributes một cách có điều kiện.
function MyComponent({ isActive }) {
return (
<div className={isActive ? 'active' : ''}>Hello, World!</div>
);
}
Trong ví dụ trên, class active sẽ chỉ được thêm vào div nếu isActive là true.
JavaScript cho phép sử dụng short-circuit evaluation để thực hiện các phép toán logic mà không cần đến toán tử ba ngôi. Điều này có thể được sử dụng để thêm attributes.
function MyComponent({ isActive }) {
return (
<div className={isActive && 'active'}>Hello, World!</div>
);
}
Trong ví dụ trên, nếu isActive là true, className sẽ là active. Nếu isActive là false, JavaScript sẽ trả về false và React sẽ bỏ qua attribute này.
Bạn cũng có thể sử dụng spread operator (...) để thêm props một cách có điều kiện vào một component.
function MyComponent({ isActive }) {
const additionalProps = isActive ? { className: 'active' } : {};
return (
<div {...additionalProps}>Hello, World!</div>
);
}
Trong ví dụ trên, nếu isActive là true, additionalProps sẽ chứa một đối tượng với className là active. Nếu không, nó sẽ là một đối tượng rỗng và không có attribute nào được thêm vào div.
Một cách khác là sử dụng một hàm để tạo ra props dựa trên các điều kiện.
function getProps(isActive) {
return isActive ? { className: 'active' } : {};
}
function MyComponent({ isActive }) {
return (
<div {...getProps(isActive)}>Hello, World!</div>
);
}
Trong ví dụ này, hàm getProps trả về một đối tượng props dựa trên giá trị của isActive. Đối tượng này sau đó được truyền vào div sử dụng spread operator.
Các phương pháp trên cho phép bạn thêm các attributes vào React components một cách linh hoạt và có điều kiện, giúp tạo ra các UI động và tùy chỉnh dễ dàng hơn.
Trường hợp nào nên dùng shouldComponentUpdate() trong React?
Trong React, shouldComponentUpdate() là một phương thức vòng đời của class component, được sử dụng để cho phép hoặc ngăn chặn việc re-render của component. Bạn nên sử dụng shouldComponentUpdate() trong các trường hợp sau:
Khi bạn muốn tối ưu hóa hiệu suất của ứng dụng bằng cách ngăn chặn các lần re-render không cần thiết. shouldComponentUpdate() cho phép bạn so sánh props hoặc state hiện tại với props hoặc state mới và quyết định xem component có nên cập nhật hay không.
Trong trường hợp component của bạn nhận vào nhiều props hoặc có nhiều state, và bạn biết rằng chỉ một số thay đổi nhất định mới cần dẫn đến việc cập nhật UI. shouldComponentUpdate() có thể được sử dụng để so sánh cụ thể những phần của props hoặc state mà bạn quan tâm.
Khi dữ liệu mà component sử dụng không thay đổi, nhưng component vẫn bị re-render do thay đổi ở một phần khác của ứng dụng. Sử dụng shouldComponentUpdate() giúp bạn kiểm soát việc này và ngăn chặn re-render không cần thiết.
PureComponent và React.memo cung cấp so sánh nông (shallow comparison) tự động, nhưng nếu bạn cần một so sánh sâu hơn hoặc tùy chỉnh, shouldComponentUpdate() sẽ cần thiết.
Khi bạn có các cấu trúc dữ liệu phức tạp và muốn tránh việc sử dụng các thư viện bên ngoài hoặc logic so sánh sâu, shouldComponentUpdate() có thể giúp bạn thực hiện so sánh một cách tối ưu.
shouldComponentUpdate() có thể làm phức tạp code nếu không được quản lý cẩn thận.React.PureComponent hoặc hook React.memo cho function components để có được hiệu suất tương tự mà không cần viết shouldComponentUpdate() thủ công.shouldComponentUpdate() chỉ tồn tại trong class components. Đối với function components, bạn có thể sử dụng hook React.memo cùng với so sánh props tùy chỉnh để đạt được kết quả tương tự.Tóm lại, shouldComponentUpdate() là một công cụ hữu ích để tối ưu hóa hiệu suất của ứng dụng React bằng cách kiểm soát việc re-render của components dựa trên sự thay đổi của props và state.
React Fiber là gì? Giải thích cơ chế hoạt động?
React Fiber là một cơ chế mới cho thuật toán reconciliation của React, là nền tảng của React 16 và các phiên bản sau đó. Fiber là một cải tiến lớn so với thuật toán reconciliation cũ, giúp tối ưu hóa việc render các component và quản lý các tác vụ trong React.
Fiber giới thiệu khái niệm về "fiber" - một đơn vị công việc nhỏ trong quá trình render. Mỗi fiber đại diện cho một component và công việc cần thực hiện cho component đó. React sẽ duyệt qua cây component và tạo ra các fiber tương ứng, sau đó quản lý việc thực hiện và cập nhật các fiber này theo cách có thể dừng và tiếp tục lại.
React Fiber là một bước tiến quan trọng trong việc cải thiện cơ chế cập nhật và render của React. Nó mang lại khả năng xử lý các tác vụ một cách linh hoạt và hiệu quả, cải thiện hiệu suất và trải nghiệm người dùng, đồng thời giúp các nhà phát triển dễ dàng hơn trong việc xử lý lỗi và quản lý trạng thái ứng dụng.
Làm thế nào để thiết lập state với dynamic key name?
Để thiết lập state trong React với dynamic key name, bạn có thể sử dụng cú pháp tính toán tên thuộc tính (computed property names) trong ES6. Điều này cho phép bạn đặt tên key cho state dựa trên giá trị của một biến. Dưới đây là cách bạn có thể làm điều đó:
useState Hook trong Functional ComponentNếu bạn đang sử dụng functional component, bạn có thể sử dụng useState hook để thiết lập state. Để cập nhật state với dynamic key, bạn có thể sử dụng một hàm cập nhật state và truyền vào một object với key được tính toán:
import React, { useState } from 'react';
function MyComponent() {
const [state, setState] = useState({});
function updateState(key, value) {
setState(prevState => ({
...prevState,
[key]: value
}));
}
// Giả sử bạn muốn cập nhật state với key là giá trị của biến `dynamicKey`
const dynamicKey = 'myKey';
const value = 'myValue';
// Cập nhật state
updateState(dynamicKey, value);
// ...
}
this.setState trong Class ComponentNếu bạn đang sử dụng class component, bạn có thể sử dụng phương thức this.setState để cập nhật state. Tương tự như trên, bạn sẽ sử dụng cú pháp tính toán tên thuộc tính:
import React, { Component } from 'react';
class MyComponent extends Component {
constructor(props) {
super(props);
this.state = {};
}
updateState(key, value) {
this.setState({
[key]: value
});
}
render() {
// Giả sử bạn muốn cập nhật state với key là giá trị của biến `dynamicKey`
const dynamicKey = 'myKey';
const value = 'myValue';
// Cập nhật state
this.updateState(dynamicKey, value);
// ...
}
}
Trong cả hai ví dụ trên, [key] là cú pháp cho phép bạn sử dụng giá trị của biến key như là tên của key trong object state. Khi bạn gọi hàm updateState hoặc phương thức this.updateState, React sẽ cập nhật state với key và value mà bạn cung cấp.
Trong React, refs và findDOMNode() thì phương thức nào được ưu tiên hơn để truy cập các nút DOM hoặc các instance của component?
Trong React, việc sử dụng refs được ưu tiên hơn so với việc sử dụng findDOMNode() để truy cập các nút DOM hoặc các instance của component. Dưới đây là một số lý do chính:
React khuyến nghị sử dụng refs thay vì findDOMNode() vì findDOMNode() có thể sớm bị loại bỏ khỏi các phiên bản tương lai của React. Sử dụng refs là cách tiếp cận chính thức và được khuyến khích để truy cập DOM trong React.
Refs cung cấp một cách linh hoạt và rõ ràng hơn để truy cập các nút DOM hoặc các instance của component. Bạn có thể gán ref trực tiếp đến một phần tử DOM hoặc component class trong JSX, làm cho mã nguồn dễ đọc và bảo trì hơn.
Trong các phiên bản mới của React, findDOMNode() không hoạt động với function components. Tuy nhiên, bạn có thể sử dụng refs với function components thông qua hook useRef, mở rộng khả năng sử dụng refs trong toàn bộ ứng dụng React của bạn.
findDOMNode() thường được sử dụng khi không có cách nào khác để truy cập DOM, nhưng việc sử dụng nó có thể dẫn đến việc viết mã không tối ưu. Sử dụng refs giúp tránh việc phụ thuộc vào DOM và khuyến khích việc sử dụng dữ liệu và trạng thái để quản lý UI, phù hợp với triết lý của React.
StrictMode là một công cụ hữu ích trong React giúp phát hiện các vấn đề tiềm ẩn trong ứng dụng. Sử dụng findDOMNode() trong StrictMode sẽ gây ra cảnh báo, trong khi refs hoàn toàn tương thích với StrictMode.
Tóm lại, việc sử dụng refs được ưu tiên hơn findDOMNode() trong React vì nó phù hợp với các khuyến nghị chính thức, cung cấp tính linh hoạt và rõ ràng hơn, hỗ trợ function components, tránh sử dụng không cần thiết và tương thích với StrictMode.
Khi nào cần truyền props cho super() trong React?
Trong React, việc truyền props cho super() trong constructor của một class component là cần thiết khi bạn muốn sử dụng this.props trong constructor. Điều này đặc biệt quan trọng nếu bạn cần truy cập đến props để khởi tạo trạng thái hoặc thực hiện các thiết lập ban đầu dựa trên props.
props cho super():this.props trong constructor: Để this.props được định nghĩa trong constructor, bạn cần truyền props đến super(). Nếu không, this.props sẽ là undefined trong phạm vi của constructor.class MyComponent extends React.Component {
constructor(props) {
super(props);
console.log(this.props); // `props` sẽ được định nghĩa nếu bạn truyền `props` cho `super()`
this.state = {
myStateValue: props.initialValue // Sử dụng `props` để khởi tạo state
};
}
// ...
}
this.props trong constructor: Nếu bạn không cần truy cập this.props ngay trong constructor, bạn vẫn có thể truyền props cho super() như một thực hành tốt, nhưng nó không bắt buộc. React sẽ tự động thiết lập this.props sau khi constructor được thực thi.props cho super() hay không, this.props sẽ vẫn được định nghĩa và có thể sử dụng bình thường trong các phương thức khác của class, bao gồm render() và các phương thức vòng đời khác.props trong class components vẫn là kiến thức quan trọng.Tóm lại, việc truyền props cho super() trong constructor của class component là cần thiết khi bạn muốn sử dụng this.props ngay trong constructor để khởi tạo trạng thái hoặc thực hiện các thiết lập ban đầu dựa trên props.
Làm thế nào để sử dụng Polymer trong React?
Polymer và ReactJS là hai thư viện JavaScript phổ biến được sử dụng để xây dựng giao diện người dùng web, nhưng chúng hoạt động dựa trên hai mô hình khác nhau. Polymer tập trung vào việc sử dụng Web Components - một tập hợp các tiêu chuẩn web cho phép tạo ra các thành phần giao diện người dùng tùy chỉnh và tái sử dụng, trong khi ReactJS sử dụng một mô hình dựa trên component JavaScript để xây dựng UI.
Để sử dụng Polymer trong một ứng dụng ReactJS, bạn cần tích hợp Web Components của Polymer vào trong các component React. Dưới đây là một số bước cơ bản để thực hiện điều này:
Trước tiên, bạn cần cài đặt Polymer và các Web Components mà bạn muốn sử dụng trong ứng dụng React của mình. Bạn có thể cài đặt chúng thông qua npm hoặc bower, tùy thuộc vào cấu hình dự án của bạn.
Sau khi đã cài đặt các Web Components của Polymer, bạn cần import chúng vào file JavaScript hoặc TypeScript mà bạn muốn sử dụng chúng. Điều này đảm bảo rằng các Web Components được đăng ký và sẵn sàng để sử dụng trong ứng dụng của bạn.
import '@polymer/paper-button/paper-button.js';
Bây giờ bạn có thể sử dụng các Web Components như một phần của UI trong các component React. Bạn chỉ cần sử dụng thẻ tương ứng của Web Component như một phần tử JSX trong render method của component React.
function MyComponent() {
return (
<div>
<h1>Hello, Polymer!</h1>
<paper-button raised>Click me</paper-button>
</div>
);
}
Để xử lý sự kiện từ Web Components trong React, bạn có thể sử dụng các thuộc tính sự kiện thông thường của JSX. Ví dụ, nếu bạn muốn xử lý sự kiện click của một paper-button:
function MyComponent() {
const handleClick = () => {
console.log('Button clicked!');
};
return (
<div>
<h1>Hello, Polymer!</h1>
<paper-button raised onClick={handleClick}>Click me</paper-button>
</div>
);
}
ref để truy cập trực tiếp đến Web Component từ React để gọi các phương thức hoặc truy cập các thuộc tính không được hỗ trợ qua props.Sử dụng Polymer trong ReactJS cho phép bạn tận dụng lợi ích của Web Components, mang lại khả năng tái sử dụng cao và bảo trì dễ dàng cho các thành phần giao diện người dùng của bạn.
So sánh Flux với MVC?
Flux và MVC (Model-View-Controller) là hai kiến trúc phần mềm được sử dụng để xây dựng các ứng dụng web. Dưới đây là sự so sánh giữa chúng:
Actions, Dispatcher, Stores, và Views (thường là React components).Tóm lại, Flux và MVC đều là những kiến trúc hữu ích với những ưu và nhược điểm riêng, và sự lựa chọn giữa chúng phụ thuộc vào yêu cầu cụ thể của dự án và sở thích của nhóm phát triển. Flux thường được ưa chuộng trong các ứng dụng React do tính tương thích và cách tiếp cận dữ liệu một chiều của nó.
Sự khác biệt giữa việc sử dụng constructor và getInitialState trong React là gì?
Trong React, việc khởi tạo trạng thái (state) của một component có thể được thực hiện thông qua constructor hoặc getInitialState. Tuy nhiên, sự khác biệt giữa hai cách này chủ yếu nằm ở phiên bản của React và loại component được sử dụng (class component hay functional component).
constructorthis.state trong phương thức constructor của class.class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
// khởi tạo state ở đây
};
}
}
constructor để khởi tạo state, bạn cần gọi super(props) trước tiên để đảm bảo rằng class component kế thừa đúng cách từ React.Component.getInitialStategetInitialState là cách thức khởi tạo state trong React.createClass.var MyComponent = React.createClass({
getInitialState: function() {
return {
// khởi tạo state ở đây
};
}
});
getInitialState chỉ được sử dụng trong React.createClass, một cú pháp đã bị loại bỏ trong các phiên bản mới của React. Đối với các phiên bản mới, bạn nên sử dụng class components với constructor hoặc functional components với Hooks (ví dụ: useState).constructor để khởi tạo state.useState) để quản lý state trong functional components, thay thế cho cả constructor và getInitialState.getInitialState được sử dụng trong cú pháp cũ React.createClass và không còn được khuyến khích sử dụng trong các phiên bản mới của React.Như vậy, sự khác biệt chính giữa việc sử dụng constructor và getInitialState nằm ở phiên bản React và loại component được sử dụng.
Tại sao chúng ta có cả 2 loại input controlled input và uncontrolled input?
Người phỏng vấn muốn thấy ở đây là một sự hiểu biết vững chắc về khái niệm React cơ bản. Một controlled input nhận 1 prop làm giá trị hiện tại của nó, và 1 prop là 1 callback để thay đổi giá trị đó, nó là một React way
<input type="text" value={value} onChange={this.handleChange} />
Một uncontrolled input lưu giá trị của nó bên trong, sử dụng DOM API. Ví dụ dưới đây chúng ta không dùng value và onChange, mà dùng ref():
<input type="text" ref={this.textInput} />
Và chúng ta có thể truy xuất giá trị của nó như sau:
this.textInput.current.value;
Người phỏng vấn muốn được nghe nhiều thứ hơn có bất kì props nào để sử dụng các uncontrolled component không, có sự khác biệt nào về hiệu suất không? Với cách dùng controlled input thì dữ liệu của bạn (state) và UI (inputs) luôn đồng bộ với nhau, nghĩa là bạn phải cập nhật state của component, điều đó sẽ kích hoạt tiến trình React reconciliation. Còn với cách dùng uncontrolled input thì không cần điều đó, bạn chỉ giữ giá trị input bên trong phần tử DOM của input đó.
Tại sao các class method cần phải được bind với một class instance?
Trong React và JavaScript nói chung, các class method cần phải được bind với một class instance để đảm bảo rằng this trong phương thức đó luôn luôn tham chiếu đúng đến instance của class khi phương thức được gọi. Điều này đặc biệt quan trọng khi bạn sử dụng phương thức đó làm callback, ví dụ như trong sự kiện click hoặc trong các hàm bất đồng bộ.
Đảm bảo this tham chiếu đúng: Trong JavaScript, giá trị của this trong một phương thức phụ thuộc vào cách phương thức đó được gọi. Khi một phương thức class được truyền như một callback mà không được bind, this sẽ không tham chiếu đến instance của class mà thay vào đó là undefined (trong strict mode) hoặc global object (trong non-strict mode), dẫn đến lỗi khi bạn cố gắng truy cập các thuộc tính hoặc phương thức khác của class thông qua this.
Sử dụng trong Callbacks và Event Handlers: Trong React, thường xuyên cần truyền các phương thức class như là callbacks cho các sự kiện, ví dụ như onClick. Để đảm bảo rằng this trong các phương thức đó tham chiếu đúng đến component, bạn cần bind chúng trong constructor hoặc sử dụng các cú pháp khác như class fields syntax hoặc arrow functions trong class properties.
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
// `this` tham chiếu đúng đến instance của MyComponent
}
}
class MyComponent extends React.Component {
handleClick = () => {
// `this` tham chiếu đúng đến instance của MyComponent
}
}
class MyComponent extends React.Component {
handleClick() {
// `this` tham chiếu đúng đến instance của MyComponent
}
render() {
return <button onClick={() => this.handleClick()}>Click me</button>;
}
}
Tóm lại, việc bind các class method với class instance là cần thiết để đảm bảo this tham chiếu đúng trong các tình huống sử dụng method như callbacks hoặc event handlers, giúp tránh các lỗi không mong muốn liên quan đến this không được định nghĩa.
Sự khác biệt giữa event handling của HTML và React là gì?
Sự khác biệt giữa event handling trong HTML thuần và trong React chủ yếu nằm ở cách sự kiện được xử lý và cú pháp được sử dụng. Dưới đây là một số điểm khác biệt chính:
on. Ví dụ: onclick="handleClick()".onClick={handleClick}.thisthis tham chiếu đến phần tử DOM mà sự kiện được gắn vào.this trong các phương thức xử lý sự kiện không tự động tham chiếu đến instance của class, trừ khi bạn rõ ràng bind this trong constructor hoặc sử dụng arrow function.event Objectevent cho hàm xử lý sự kiện, chứa thông tin về sự kiện đã xảy ra. Tuy nhiên, React bọc đối tượng event gốc của trình duyệt vào trong một đối tượng SyntheticEvent để đảm bảo tính nhất quán của đối tượng event trên các trình duyệt khác nhau.e.preventDefault()e.preventDefault() trong hàm xử lý sự kiện để ngăn chặn hành vi mặc định của trình duyệt. Trong React, bạn thực hiện điều này trong đối tượng SyntheticEvent.SyntheticEvent, trong khi với HTML thuần, bạn có thể cần phải xử lý các sự khác biệt giữa các trình duyệt bằng tay.Tóm lại, React cung cấp một cách tiếp cận thống nhất và dễ dàng hơn để xử lý sự kiện so với HTML thuần, đồng thời giúp đảm bảo tính nhất quán trên các trình duyệt và dễ dàng quản lý context this trong các phương thức xử lý sự kiện.
React khác với AngularJS (1.x) như thế nào?
React và AngularJS (1.x) là hai thư viện/framework phổ biến trong việc xây dựng giao diện người dùng (UI) cho các ứng dụng web, nhưng chúng có những khác biệt cơ bản:
React:
AngularJS (1.x):
React:
AngularJS (1.x):
React:
AngularJS (1.x):
ng-model, ng-repeat, ng-if, và cho phép tạo custom directive.React:
AngularJS (1.x):
React:
AngularJS (1.x):
Tóm lại, React và AngularJS (1.x) đều có những ưu và nhược điểm riêng, và sự lựa chọn giữa chúng phụ thuộc vào yêu cầu cụ thể của dự án, kinh nghiệm của đội ngũ phát triển, và các yếu tố khác như kích thước và độ phức tạp của ứng dụng.
Làm sao để ngăn các React component re-render?
Trong React, việc ngăn chặn các component không cần thiết phải re-render có thể giúp tối ưu hóa hiệu suất ứng dụng. Dưới đây là một số cách để ngăn chặn re-render:
React.memo cho Function ComponentsReact.memo là một higher order component (HOC) mà nó chỉ cho phép component re-render khi props của nó thay đổi.
const MyComponent = React.memo(function MyComponent(props) {
/* render using props */
});
Khi props không thay đổi, MyComponent sẽ không re-render.
shouldComponentUpdate trong Class ComponentsPhương thức shouldComponentUpdate cho phép bạn quyết định xem một component có nên cập nhật hay không dựa trên sự thay đổi của props hoặc state.
class MyComponent extends React.Component {
shouldComponentUpdate(nextProps, nextState) {
// return true nếu component cần cập nhật
// return false nếu không
}
}
React.PureComponent giống như React.Component nhưng nó thêm một shouldComponentUpdate() với một shallow prop và state comparison.
class MyComponent extends React.PureComponent {
// ...
}
Nếu props hoặc state của component không thay đổi, component sẽ không re-render.
useMemo và useCallbackKhi sử dụng function components, bạn có thể sử dụng hook useMemo để memoize các giá trị và useCallback để memoize các hàm.
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
const memoizedCallback = useCallback(() => {
doSomething(a, b);
}, [a, b]);
Cả hai hook này giúp tránh việc tính toán không cần thiết hoặc tạo ra các hàm mới trong mỗi lần render.
Khi sử dụng React Context, hãy chắc chắn rằng các consumer component không re-render mỗi khi provider value thay đổi. Bạn có thể sử dụng React.memo hoặc useMemo để ngăn chặn điều này.
Đảm bảo rằng các props bạn truyền vào component không thay đổi giữa các lần render nếu không cần thiết. Điều này bao gồm việc tránh việc truyền các object hoặc array mới được tạo trong mỗi lần render.
Khi sử dụng state hoặc context, hãy chia nhỏ nó thành các phần nhỏ hơn nếu có thể để chỉ những phần cần thiết của component được cập nhật khi state hoặc context thay đổi.
Bằng cách áp dụng các phương pháp trên, bạn có thể giảm số lượng re-render không cần thiết và cải thiện hiệu suất của ứng dụng React.
Giải thích việc sử dụng React Hook useLayoutEffect?
Hook useLayoutEffect trong React được sử dụng để thực hiện các hiệu ứng có ảnh hưởng đến bố cục (layout) trước khi trình duyệt vẽ (paint) các thay đổi lên màn hình. Nó hoạt động tương tự như useEffect, nhưng với một điểm khác biệt quan trọng: useLayoutEffect được thực thi đồng bộ và sẽ chặn việc vẽ để thực thi mã của mình.
Cụ thể, useLayoutEffect được gọi ngay sau khi React cập nhật DOM (Document Object Model), nhưng trước khi trình duyệt có cơ hội vẽ lại bất kỳ thay đổi nào lên màn hình. Điều này cho phép bạn đọc từ và viết vào DOM, thực hiện các thay đổi hoặc đo lường mà không gây ra hiện tượng nhấp nháy hoặc hiệu ứng không mong muốn do việc vẽ lại.
Một số trường hợp sử dụng phổ biến của useLayoutEffect bao gồm:
Tuy nhiên, do useLayoutEffect chạy đồng bộ và có thể chặn việc vẽ lại của trình duyệt, nó có thể ảnh hưởng đến hiệu suất nếu được sử dụng quá mức. Do đó, bạn nên sử dụng useEffect cho hầu hết các trường hợp và chỉ chuyển sang useLayoutEffect khi cần thiết để xử lý các thay đổi liên quan đến bố cục hoặc khi useEffect không cung cấp kết quả mong muốn.
Làm thế nào để force một component re-render với Hooks trong React?
Để buộc một thành phần tái render với Hooks trong React, bạn có thể sử dụng một số phương pháp khác nhau. Một trong những cách phổ biến là sử dụng một biến trạng thái (state variable) để kích hoạt việc tái render. Dưới đây là một số cách tiếp cận:
Bạn có thể tạo một biến trạng thái không được sử dụng trực tiếp trong render, nhưng thay đổi giá trị của nó sẽ buộc component tái render.
Ví dụ:
```javascript
const [, forceUpdate] = React.useState();
const reRender = () => forceUpdate({});
```
Trong ví dụ trên, forceUpdate là một hàm mà khi được gọi, sẽ buộc component tái render bằng cách cập nhật trạng thái với một đối tượng mới.
Một cách khác là sử dụng useReducer để tạo một hàm tái render. useReducer thường được sử dụng cho trạng thái phức tạp hơn, nhưng bạn cũng có thể sử dụng nó cho mục đích này.
Ví dụ:
```javascript
const [, forceUpdate] = React.useReducer((x) => x + 1, 0);
```
Trong ví dụ này, mỗi lần forceUpdate được gọi, nó sẽ tăng giá trị trạng thái lên 1, từ đó kích hoạt việc tái render.
Bạn cũng có thể tạo một custom hook để tái sử dụng logic buộc tái render trong nhiều component.
Ví dụ:
function useForceUpdate() {
const [, setTick] = useState(0);
const update = useCallback(() => {
setTick((tick) => tick + 1);
}, []);
return update;
}
useForceUpdate là một custom hook mà khi được gọi, sẽ tăng giá trị của biến tick, từ đó buộc component tái render.Nhớ rằng, việc buộc tái render là một phương pháp nên được sử dụng một cách cẩn thận và chỉ trong những trường hợp cần thiết, vì nó có thể làm giảm hiệu suất của ứng dụng.
Hooks có thay thế render props và** higher-order components (HOC)** không?
Hooks không hoàn toàn thay thế render props và higher-order components (HOC), nhưng chúng cung cấp một cách đơn giản hơn để chia sẻ logic giữa các components mà không cần tăng cấp độ lồng nhau trong cây components của bạn. Mặc dù Hooks có thể thay thế HOCs và Render Props trong nhiều trường hợp bằng cách giảm bớt sự phức tạp và lồng nhau, nhưng cả HOCs và Render Props vẫn có những ưu điểm riêng và có thể được sử dụng trong các tình huống cụ thể.
HOC là một mẫu thiết kế độc lập với React, trong khi Hooks là một phần của React. Bạn có thể ghép nối HOCs như các hàm, nhưng Hooks không thể ghép nối. HOC thêm một thành phần khác vào hệ thống phân cấp của components, điều này có thể được kiểm tra trong DevTools.
Tuy nhiên, Hooks giúp tránh được sự phức tạp và khó hiểu khi sử dụng HOCs và Render Props bằng cách cho phép bạn sử dụng trạng thái và các tính năng khác của React mà không cần viết class. Hooks cũng cho phép tạo ra các custom Hooks để chia sẻ logic trạng thái giữa các components một cách dễ dàng.
Như vậy, trong khi Hooks cung cấp một cách tiếp cận mới và đơn giản hơn để chia sẻ logic giữa các components và có thể thay thế HOCs và Render Props trong nhiều trường hợp, cả HOCs và Render Props vẫn có vai trò và ứng dụng riêng trong một số tình huống cụ thể.
Những hạn chế nào bạn không nên làm trong hàm render của một component trong React?
Trong React, phương thức render của một component là nơi quan trọng để mô tả cấu trúc UI mà component sẽ hiển thị. Tuy nhiên, có một số hạn chế và thực hành không nên thực hiện trong phương thức render để tránh gặp phải vấn đề về hiệu suất và bảo trì mã nguồn:
Math.random() không nên được thực hiện trong render vì chúng có thể dẫn đến hành vi không mong muốn và làm cho việc kiểm soát trạng thái trở nên khó khăn.setState trực tiếp: Gọi setState trong render có thể dẫn đến vòng lặp vô tận vì mỗi lần setState được gọi, component sẽ re-render.render: Việc khai báo hàm hoặc đối tượng mới trong render sẽ tạo ra một thực thể mới mỗi khi component re-render, dẫn đến việc không thể so sánh props hoặc state hiệu quả và gây ra re-render không cần thiết.render có thể làm cho mã nguồn trở nên khó đọc và khó bảo trì. Thay vào đó, hãy tách chúng ra thành các hàm hoặc component nhỏ hơn.render có thể làm tăng kích thước của DOM và ảnh hưởng đến hiệu suất render. Sử dụng CSS hoặc styled-components là một lựa chọn tốt hơn.render hoặc sử dụng memoization để giảm thiểu việc tính toán lại không cần thiết.Tóm lại, phương thức render nên được giữ đơn giản và chỉ chứa mã để mô tả UI. Việc tuân thủ các hạn chế trên giúp đảm bảo rằng component của bạn sẽ hiệu quả về mặt hiệu suất và dễ dàng bảo trì hơn.
Làm thế nào để cập nhật status trên một đối tượng lồng nhau với useState()?
Để cập nhật trạng thái trên một đối tượng lồng nhau sử dụng hook useState() trong React, bạn cần tạo một bản sao của đối tượng, cập nhật giá trị cần thiết trong bản sao đó, và sau đó sử dụng hàm cập nhật trạng thái với đối tượng mới. Một cách phổ biến để thực hiện điều này là sử dụng toán tử spread (...) để tạo bản sao và cập nhật giá trị.
Ví dụ, giả sử bạn có trạng thái đối tượng như sau:
const [user, setUser] = useState({
name: 'John Doe',
address: {
street: '123 Main St',
city: 'Anytown'
}
});
Để cập nhật thành phố trong địa chỉ, bạn có thể làm như sau:
setUser((prevUser) => ({
...prevUser,
address: {
...prevUser.address,
city: 'New City'
}
}));
Trong ví dụ trên, ...prevUser tạo một bản sao của đối tượng user hiện tại, và ...prevUser.address tạo một bản sao của đối tượng address. Sau đó, bạn cập nhật giá trị của city trong bản sao đó. Cuối cùng, bạn sử dụng hàm setUser với đối tượng mới đã được cập nhật.
Cách tiếp cận này đảm bảo rằng bạn không trực tiếp sửa đổi trạng thái hiện tại (điều này có thể gây ra các vấn đề về hiệu suất và khả năng dự đoán của ứng dụng) và giữ cho trạng thái của ứng dụng không bị thay đổi (immutable), phù hợp với các nguyên tắc của React.
Tại sao chúng ta cần 1 thuộc tính key trong React?
Trong React, thuộc tính "key" là một thuộc tính đặc biệt và quan trọng được sử dụng khi render một danh sách các phần tử để giúp React xác định các phần tử nào đã thay đổi, được thêm vào, hoặc bị xóa. Các lý do chính cần sử dụng thuộc tính "key" bao gồm:
Khi danh sách dữ liệu thay đổi, React sẽ sử dụng thuộc tính "key" để so sánh các phần tử trong danh sách mới với danh sách cũ và xác định nhanh chóng các phần tử nào cần được cập nhật, thêm vào, hoặc xóa bỏ. Điều này giúp tối ưu hóa quá trình cập nhật DOM và cải thiện hiệu suất của ứng dụng.
Trong trường hợp các component có trạng thái nội bộ (state), việc sử dụng "key" giúp React quản lý trạng thái của các component một cách chính xác khi danh sách dữ liệu thay đổi. Nếu không có "key", React có thể sẽ không đúng trong việc tái sử dụng các component, dẫn đến lỗi hoặc hành vi không mong muốn trong UI.
Khi không sử dụng "key" hoặc sử dụng "key" không đúng cách (ví dụ: sử dụng chỉ số mảng làm "key"), React có thể sẽ không cập nhật DOM một cách chính xác khi dữ liệu thay đổi. Điều này có thể dẫn đến các lỗi UI, như hiển thị dữ liệu sai hoặc không cập nhật UI khi dữ liệu thay đổi.
Khi cần tái sử dụng hoặc sắp xếp lại các component trong danh sách mà không mất trạng thái của chúng, "key" giúp React xác định chính xác các component này để tái sử dụng hoặc sắp xếp mà không cần phải tạo lại từ đầu.
Thuộc tính "key" là một phần quan trọng trong việc xây dựng các ứng dụng React hiệu quả và hiệu suất cao. Việc sử dụng "key" một cách chính xác giúp đảm bảo rằng React có thể theo dõi và cập nhật danh sách các phần tử một cách chính xác, giúp ứng dụng của bạn hoạt động mượt mà và đáng tin cậy hơn.
Khi một ứng dụng React bị render chậm, bạn sẽ làm thế nào để tìm ra nguyên nhân gây ra việc đó?
Một trong những nguyên nhân phổ biến nhất gây ra việc render chậm trong các ứng dụng React là khi các component được re-render không cần thiết. Có hai công cụ được cung cấp bởi React có ích trong những trường hợp sau:
React.memo(): Điều này ngăn việc re-render không cần thiết của function component.PureComponent: Điều này ngăn việc re-render không cần thiết của class component.Cả hai công cụ này đều dựa trên sự so sánh nông (shallow comparison) của các props được truyền vào component — nếu props không thay đổi, thì component sẽ không re-render. Mặc dù cả hai công cụ đều rất hữu ích, nhưng so sánh nông sẽ ảnh hưởng về hiệu suất, vì vậy cả hai đều có thể có tác động tiêu cực đến hiệu suất nếu sử dụng không đúng cách.

Một cách tối ưu hơn đó là chúng ta sử dụng React Profiler, hiệu suất có thể được đo lường trước và sau khi sử dụng các công cụ này để đảm bảo rằng hiệu suất thực sự được cải thiện bằng cách thực hiện một thay đổi nhất định.
Ưu điểm của React so với Vuejs là gì?
Ưu điểm của React so với VueJS bao gồm:
React được phát triển và duy trì bởi Facebook, có một cộng đồng lớn với hàng nghìn nhà phát triển và công ty sử dụng nó. Điều này đảm bảo rằng React có nhiều tài nguyên học tập, thư viện bổ sung, và hỗ trợ từ cộng đồng.
React có thể dễ dàng tích hợp với các thư viện khác như Redux, MobX, hoặc thậm chí là Vue trong một số trường hợp. Điều này cho phép các nhà phát triển tận dụng sức mạnh của React trong khi vẫn sử dụng các công cụ khác mà họ ưa thích.
React khuyến khích việc phát triển dựa trên component, giúp tái sử dụng code và quản lý trạng thái trở nên dễ dàng hơn. Các component có thể được đóng gói và tái sử dụng trong các dự án khác nhau, giúp tăng tốc độ phát triển và bảo trì.
React sử dụng Virtual DOM để tối ưu hóa việc cập nhật giao diện người dùng. Khi trạng thái của ứng dụng thay đổi, React sẽ so sánh sự thay đổi trong Virtual DOM với DOM thực tế và chỉ cập nhật những phần cần thiết, giúp tăng hiệu suất.
React sử dụng JSX, một cú pháp mở rộng của JavaScript, cho phép viết HTML trong JavaScript. Điều này giúp việc viết và đọc code trở nên dễ dàng hơn, đặc biệt là khi làm việc với các cấu trúc UI phức tạp.
Ngoài Facebook, nhiều công ty lớn khác như Airbnb, Netflix, và Dropbox cũng sử dụng và hỗ trợ React. Điều này không chỉ chứng minh sức mạnh và độ tin cậy của React mà còn đảm bảo rằng nó sẽ tiếp tục được phát triển và cải thiện.
React hỗ trợ server-side rendering (SSR) thông qua thư viện như Next.js, giúp cải thiện thời gian tải trang và SEO cho các ứng dụng web.
React có thể được sử dụng để phát triển ứng dụng di động với React Native, cho phép chia sẻ logic ứng dụng giữa web và mobile, giảm thời gian và chi phí phát triển.
Tóm lại, mặc dù cả React và VueJS đều có những ưu điểm riêng, React nổi bật với cộng đồng lớn, tích hợp linh hoạt, tái sử dụng component, Virtual DOM, JSX, hỗ trợ từ các công ty lớn, SSR, và khả năng phát triển ứng dụng di động với React Native.
Khi nào nên sử dụng forceUpdate trong một React component?
Trong React, forceUpdate() là một phương thức của class component, được sử dụng để buộc một component re-render, bỏ qua phương thức shouldComponentUpdate(). Tuy nhiên, việc sử dụng forceUpdate() thường không được khuyến khích và chỉ nên sử dụng trong một số trường hợp cụ thể:
Nếu component của bạn không phụ thuộc vào state hoặc props để render, và bạn cần cập nhật UI dựa trên sự thay đổi của một số dữ liệu bên ngoài mà React không thể phát hiện, forceUpdate() có thể được sử dụng để buộc component re-render.
Trong trường hợp bạn đang sử dụng một thư viện DOM bên ngoài không phải của React, và thư viện đó thay đổi DOM mà không thông qua React, forceUpdate() có thể được sử dụng để đồng bộ hóa lại với React sau khi thư viện thực hiện thay đổi.
Trong một số trường hợp hiếm hoi, bạn có thể muốn tối ưu hóa hiệu suất bằng cách bỏ qua việc kiểm tra shouldComponentUpdate(), và forceUpdate() có thể được sử dụng để đạt được điều này. Tuy nhiên, điều này nên được xem xét cẩn thận vì nó có thể dẫn đến việc re-render không cần thiết và làm giảm hiệu suất.
forceUpdate() có thể dẫn đến việc viết mã không tối ưu và khó bảo trì. Trong hầu hết các trường hợp, việc sử dụng state và props để quản lý re-render là đủ và được khuyến khích.forceUpdate() không gọi shouldComponentUpdate(), nhưng vẫn gọi các phương thức vòng đời khác như componentWillUpdate(), componentDidUpdate(), và render().forceUpdate(). Thay vào đó, bạn có thể sử dụng hook useState hoặc useReducer để buộc re-render.Tóm lại, forceUpdate() nên được sử dụng một cách thận trọng và chỉ trong những trường hợp cần thiết khi các cơ chế thông thường của React không đáp ứng được yêu cầu của ứng dụng.
So sánh redux thunk và redux saga?
Redux Thunk và Redux Saga đều là middleware trong Redux được sử dụng để xử lý các tác vụ bất đồng bộ như tương tác với API hoặc thực hiện logic phức tạp trước khi cập nhật state. Tuy nhiên, chúng có những điểm khác biệt cơ bản về cách thức hoạt động và cú pháp.
Tóm lại, lựa chọn giữa Redux Thunk và Redux Saga phụ thuộc vào độ phức tạp của ứng dụng, sở thích cá nhân và kinh nghiệm làm việc với JavaScript của bạn. Thunk thường được ưa chuộng cho các dự án nhỏ hơn và ít phức tạp, trong khi Saga là lựa chọn tốt cho các ứng dụng lớn hơn và yêu cầu nhiều tác vụ bất đồng bộ phức tạp.
Làm thế nào để tạo Props Proxy cho HOC component?
Trong React, Props Proxy là một kỹ thuật trong Higher-Order Components (HOC) mà thông qua đó HOC có thể thay đổi, thêm, hoặc loại bỏ props trước khi chúng được truyền đến Wrapped Component (component được bọc bởi HOC). Đây là một cách để tùy chỉnh hoặc thay đổi hành vi của một component mà không cần sửa đổi mã nguồn của chính component đó.
Để tạo một Props Proxy cho một HOC, bạn sẽ tạo một function mà nhận vào một component và trả về một component mới. Trong function này, bạn có thể thay đổi props trước khi chúng được truyền đến Wrapped Component.
Dưới đây là một ví dụ về cách tạo một Props Proxy HOC:
import React from 'react';
// Đây là HOC Props Proxy
function withPropsProxy(WrappedComponent) {
// Trả về một component mới
return class extends React.Component {
render() {
// Tạo một bản sao của props
const newProps = {
...this.props,
// Thêm, thay đổi hoặc loại bỏ các props tại đây
extraProp: 'This is an extra prop!'
};
// Truyền newProps đến WrappedComponent
return <WrappedComponent {...newProps} />;
}
};
}
// Sử dụng HOC với một component bất kỳ
const EnhancedComponent = withPropsProxy(MyComponent);
Trong ví dụ trên, withPropsProxy là một HOC mà tạo ra một Props Proxy. Nó nhận vào WrappedComponent, tạo một bản sao của props hiện tại, thêm một extraProp, và sau đó truyền newProps đến WrappedComponent.
WrappedComponent cần để hoạt động đúng đắn.Tóm lại, Props Proxy là một kỹ thuật hữu ích trong việc tạo ra các HOC để tùy chỉnh hành vi của các component mà không cần sửa đổi trực tiếp mã nguồn của chúng.
Thứ tự của các hook useInsertionEffect, useEffect và useLayoutEffect trong quá trình tạo ra component là gì?
Trong quá trình tạo ra và cập nhật một component trong React, thứ tự thực thi của các hook useInsertionEffect, useEffect và useLayoutEffect được xác định như sau:
Tóm lại, thứ tự thực thi của các hook trong quá trình tạo ra và cập nhật component là: useInsertionEffect chạy trước, tiếp theo là useLayoutEffect, và cuối cùng là useEffect. Sự phân biệt này giúp đảm bảo rằng các thay đổi về style được áp dụng trước khi màn hình được vẽ lại, các thay đổi về layout được xử lý trước khi người dùng nhìn thấy giao diện, và các side effects không ảnh hưởng đến việc vẽ giao diện được xử lý sau cùng.
Khi nào bạn muốn sử dụng useLayoutEffect thay thế cho useEffect?
Bạn sẽ muốn tránh sử dụng useEffect và sử dụng useLayoutEffect thay thế khi bạn cần thực hiện các thay đổi trên DOM hoặc cần thực hiện các phép đo DOM trước khi trình duyệt cập nhật màn hình (repaint). Điều này giúp tránh tình trạng nhấp nháy hoặc không đồng bộ về giao diện người dùng mà người dùng có thể nhận thấy nếu bạn sử dụng useEffect.
useLayoutEffect chạy đồng bộ ngay sau khi React thực hiện các thay đổi DOM nhưng trước khi trình duyệt cập nhật màn hình. Điều này có nghĩa là bạn có thể sử dụng useLayoutEffect để đọc từ và viết vào DOM mà không gây ra hiện tượng nhấp nháy hoặc hiển thị trạng thái không mong muốn trên giao diện người dùng.
Một ví dụ cụ thể khi bạn muốn sử dụng useLayoutEffect thay vì useEffect là khi bạn cần thực hiện các hoạt động như cuộn tự động đến một vị trí cụ thể trong một danh sách hoặc điều chỉnh kích thước của một phần tử dựa trên kích thước của phần tử khác. Trong những trường hợp này, việc sử dụng useLayoutEffect giúp đảm bảo rằng các thay đổi được thực hiện một cách mượt mà và không gây ra hiện tượng nhấp nháy hoặc hiển thị không đúng trên giao diện người dùng trước khi trình duyệt cập nhật màn hình.