24 min read

Chuẩn Bị Phỏng Vấn: 50 Câu Hỏi và Trả Lời Về React.js

Câu hỏi phỏng vấn: React.js

Để có được một công việc trong lĩnh vực React.js đòi hỏi bạn phải hiểu sâu sắc về các khái niệm cốt lõi, tính năng và các phương pháp hay nhất của nó. Hướng dẫn này giúp bạn chuẩn bị cho các cuộc phỏng vấn bằng cách đề cập đến các câu hỏi thiết yếu với câu trả lời chi tiết và ví dụ.

1. React.js là gì?

Trả lời: React.js là một thư viện JavaScript mã nguồn mở được phát triển bởi Facebook để xây dựng giao diện người dùng hoặc các thành phần UI. Nó tập trung vào việc xây dựng các thành phần UI có thể tái sử dụng và quản lý trạng thái của các thành phần này một cách hiệu quả.

2. Các tính năng chính của React.js là gì?

Trả lời: React.js có một số tính năng chính:

  • Virtual DOM: Một bản sao nhẹ của DOM thực tế mà React cập nhật và so sánh để tính toán các cập nhật tối thiểu cần thiết cho DOM thực tế.
  • JSX: Một phần mở rộng cú pháp cho JavaScript cho phép bạn viết mã giống HTML trong mã JavaScript của mình.
  • Reusable Components: Các khối xây dựng đóng gói hành vi và có thể được sử dụng lại trên toàn ứng dụng.
  • Unidirectional Data Flow: Dữ liệu luân chuyển theo một hướng, giúp dễ dàng gỡ lỗi và lý luận về trạng thái của ứng dụng.

3. JSX là gì?

Trả lời: JSX (JavaScript XML) là một phần mở rộng cú pháp cho JavaScript cho phép bạn viết mã giống HTML trong mã JavaScript của mình. Các thẻ JSX được chuyển đổi thành các đối tượng JavaScript mà React sử dụng để xây dựng DOM.

Ví dụ:

const element = <h1>Xin chào, React!</h1>;

4. Sự khác biệt giữa Element và Component trong React là gì?

Trả lời:

  • Element: Một đối tượng đơn giản mô tả một phiên bản component hoặc một nút DOM. Nó chỉ định loại của component và các thuộc tính của nó. Các element là bất biến và mô tả UI tại một thời điểm nhất định.
  • Component: Một hàm hoặc lớp tùy chọn chấp nhận đầu vào (props) và trả về một element React. Các component có thể là hàm hoặc dựa trên lớp.

Ví dụ:

const element = <Element Component />;

5. Props trong React là gì?

Trả lời: Props (viết tắt của properties) là đầu vào cho một component React cho phép bạn truyền dữ liệu từ component cha sang component con. Chúng chỉ đọc và bất biến.

Ví dụ:

function ChildComponent(props) {
  return <div>{props.message}</div>;
}

function ParentComponent() {
  return <ChildComponent message="Xin chào từ component cha!" />;
}

6. State trong React là gì?

Trả lời: State là một cấu trúc dữ liệu chứa dữ liệu động của component và xác định hành vi của component. State có thể thay đổi và có thể được thay đổi bằng phương thức setState.

Ví dụ:

class Counter extends React.Component {
  constructor(props) {
    super(props);
    this.state = { count: 0 };
  }

  increment = () => {
    this.setState({ count: this.state.count + 1 });
  };

  render() {
    return (
      <div>
        <p>Count: {this.state.count}</p>
        <button onClick={this.increment}>Increment</button>
      </div>
    );
  }
}

7. Sự khác biệt giữa state và props là gì?

Trả lời:

  • State: Được quản lý trong component và có thể thay đổi theo thời gian. Nó được sử dụng để kiểm soát hành vi của component và kết xuất đầu ra.
  • Props: Bất biến và được truyền từ component cha sang component con. Chúng chỉ đọc và không thể thay đổi trực tiếp bởi component con.

8. Controlled component trong React là gì?

Trả lời: Controlled component là một component có giá trị được kiểm soát bởi React chứ không phải bởi DOM. Trạng thái của component là nguồn chân lý duy nhất và giá trị của phần tử biểu mẫu đầu vào được liên kết với trạng thái đó.

Ví dụ:

class InputComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = { inputValue: "" };
  }

  handleChange = (event) => {
    this.setState({ inputValue: event.target.value });
  };

  render() {
    return (
      <input
        type="text"
        value={this.state.inputValue}
        onChange={this.handleChange}
      />
    );
  }
}

9. Mục đích của thuộc tính key trong danh sách React là gì?

Trả lời: Thuộc tính key được React sử dụng để xác định các mục đã thay đổi, được thêm hoặc bị xóa khỏi danh sách, cải thiện hiệu suất và ngăn chặn hành vi không mong muốn. Các key phải là duy nhất giữa các anh chị em.

Ví dụ:

const items = ["Apple", "Banana", "Cherry"];
const listItems = items.map((item) => <li key={item}>{item}</li>);

10. Context trong React là gì?

Trả lời: Context cung cấp một cách để truyền dữ liệu qua cây component mà không cần phải truyền props xuống thủ công ở mọi cấp độ. Nó rất hữu ích cho dữ liệu toàn cục như cài đặt chủ đề hoặc xác thực người dùng.

Ví dụ:

const ThemeContext = React.createContext("light");

function ThemedButton() {
  return (
    <ThemeContext.Consumer>
      {(theme) => <button style={{ background: theme }}>Button</button>}
    </ThemeContext.Consumer>
  );
}

function App() {
  return (
    <ThemeContext.Provider value="dark">
      <ThemedButton />
    </ThemeContext.Provider>
  );
}

11. Tầm quan trọng của refs trong React là gì?

Trả lời: Refs được sử dụng để tham chiếu các phần tử DOM hoặc các phiên bản component lớp trong React. Chúng rất hữu ích để truy cập trực tiếp vào DOM, đo lường các nút hoặc kích hoạt các hoạt ảnh mệnh lệnh.

Ví dụ:

class InputComponent extends React.Component {
  constructor(props) {
    super(props);
    this.inputRef = React.createRef();
  }

  focusInput = () => {
    this.inputRef.current.focus();
  };

  render() {
    return (
      <div>
        <input ref={this.inputRef} />
        <button onClick={this.focusInput}>Focus Input</button>
      </div>
    );
  }
}

12. Higher-order components (HOCs) trong React là gì?

Trả lời: Higher-order components là các hàm lấy một component và trả về một component mới với chức năng nâng cao. HOCs là một mô hình phổ biến để sử dụng lại logic component.

Ví dụ:

function withUsername(WrappedComponent) {
  return class extends React.Component {
    state = { username: "JohnDoe" };

    render() {
      return <WrappedComponent username={this.state.username} />;
    }
  };
}

function Profile(props) {
  return <h1>Username: {props.username}</h1>;
}

const ProfileWithUsername = withUsername(Profile);

13. Redux là gì?

Trả lời: Redux là một bộ chứa trạng thái có thể dự đoán cho các ứng dụng JavaScript được sử dụng để quản lý trạng thái của ứng dụng theo cách có thể dự đoán được. Nó giúp duy trì trạng thái toàn cục và xử lý logic trạng thái phức tạp.

14. Các nguyên tắc chính của Redux là gì?

Trả lời:

  • Single Source of Truth: Toàn bộ trạng thái của ứng dụng được lưu trữ trong một kho lưu trữ duy nhất, giúp dễ dàng quản lý và gỡ lỗi.
  • State is Read-Only: Cách duy nhất để thay đổi trạng thái là phát ra một hành động, một đối tượng mô tả những gì đã xảy ra.
  • Changes are Made with Pure Functions: Để chỉ định cách cây trạng thái được chuyển đổi bởi các hành động, bạn viết các reducers thuần túy.

15. Sự khác biệt giữa React.js và React Native là gì?

Trả lời:

  • React.js: Một thư viện JavaScript để xây dựng giao diện người dùng cho các ứng dụng web.
  • React Native: Một framework để xây dựng các ứng dụng di động đa nền tảng sử dụng React.

16. Hooks trong React là gì?

Trả lời: Hooks là các hàm cho phép bạn sử dụng trạng thái và các tính năng React khác trong các component hàm thay vì viết các component lớp. Chúng cung cấp một cách để trích xuất logic trạng thái từ các component để nó có thể được kiểm tra và sử dụng lại một cách độc lập.

17. Các hook cơ bản được cung cấp bởi React là gì?

Trả lời:

  • useState: Quản lý trạng thái component.
  • useEffect: Thực hiện các side effect trong các component hàm.
  • useContext: Sử dụng giá trị context.
  • useReducer: Quản lý logic trạng thái phức tạp.
  • useMemo: Ghi nhớ các giá trị để ngăn các phép tính tốn kém trên mỗi lần kết xuất.
  • useCallback: Ghi nhớ các hàm để ngăn chặn việc kết xuất lại không cần thiết của các component con.

18. Hook useEffect được sử dụng để làm gì?

Trả lời: Hook useEffect được sử dụng để thực hiện các side effect trong các component hàm, chẳng hạn như tìm nạp dữ liệu, đăng ký hoặc thay đổi DOM theo cách thủ công.

Ví dụ:

import React, { useEffect } from "react";

function DataFetchingComponent() {
  useEffect(() => {
    const fetchData = async () => {
      const response = await fetch("https://api.example.com/data");
      const data = await response.json();
      console.log(data);
    };

    fetchData();

    return () => {
      // Mã dọn dẹp
    };
  }, []);

  return <div>Data Fetching Component</div>;
}

19. Làm thế nào để bạn tối ưu hóa hiệu suất trong React?

Trả lời:

  • Memoization: Sử dụng React.memo cho các component hàm và PureComponent cho các component lớp để ngăn chặn việc kết xuất lại không cần thiết.
  • Avoid Unnecessary Re-renders: Sử dụng shouldComponentUpdate hoặc React.memo để tránh kết xuất lại nếu props hoặc state không thay đổi.
  • Use Virtualized Lists: Chỉ kết xuất các mục hiển thị trong danh sách lớn bằng cách sử dụng các thư viện như react-window hoặc react-virtualized.

20. Server-side rendering trong React là gì?

Trả lời: Server-side rendering (SSR) là quá trình kết xuất các component React ở phía máy chủ và gửi HTML cuối cùng đến máy khách, cải thiện hiệu suất và SEO. Các thư viện như Next.js và Gatsby hỗ trợ SSR.

21. Mục đích của thư viện React Router là gì?

Trả lời: React Router là một thư viện cung cấp khả năng định tuyến cho một ứng dụng React, cho phép bạn xác định nhiều tuyến đường và điều hướng giữa chúng. Nó giúp xây dựng các ứng dụng trang đơn (SPA).

Ví dụ:

import React from "react";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import Home from "./Home";
import About from "./About";

function App() {
  return (
    <Router>
      <Switch>
        <Route exact path="/" component={Home} />
        <Route path="/about" component={About} />
      </Switch>
    </Router>
  );
}

22. Làm thế nào để bạn xử lý các biểu mẫu trong React?

Trả lời: Bạn có thể xử lý các biểu mẫu trong React bằng cách sử dụng các component được kiểm soát, giữ dữ liệu biểu mẫu trong trạng thái của component và cập nhật nó dựa trên đầu vào của người dùng.

Ví dụ:

class FormComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = { inputValue: "" };
  }

  handleChange = (event) => {
    this.setState({ inputValue: event.target.value });
  };

  handleSubmit = (event) => {
    event.preventDefault();
    console.log(this.state.inputValue);
  };

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <input
          type="text"
          value={this.state.inputValue}
          onChange={this.handleChange}
        />
        <button type="submit">Submit</button>
      </form>
    );
  }
}

23. Component React.Fragment được sử dụng để làm gì?

Trả lời: React.Fragment được sử dụng để nhóm nhiều phần tử trong một phần tử cha duy nhất mà không cần thêm các nút bổ sung vào DOM.

Ví dụ:

function MyComponent() {
  return (
    <React.Fragment>
      <h1>Title</h1>
      <p>Description</p>
    </React.Fragment>
  );
}

24. Portals trong React là gì?

Trả lời: Portals cung cấp một cách để kết xuất các phần tử con vào một nút DOM tồn tại bên ngoài hệ thống phân cấp DOM của component cha, cho phép bạn kết xuất nội dung trong một phần khác của cây DOM.

Ví dụ:

const ModalComponent = ({ children }) =>
  ReactDOM.createPortal(
    <div className="modal">{children}</div>,
    document.getElementById("modal-root")
  );

25. Làm thế nào để bạn xử lý các sự kiện trong React?

Trả lời: Bạn có thể xử lý các sự kiện trong React bằng cách sử dụng tên sự kiện camelCase, truyền các trình xử lý sự kiện dưới dạng props và gọi preventDefault hoặc stopPropagation khi cần.

Ví dụ:

class ButtonComponent extends React.Component {
  handleClick = (event) => {
    event.preventDefault();
    console.log("Button clicked");
  };

  render() {
    return <button onClick={this.handleClick}>Click Me</button>;
  }
}

26. Mục đích của phương thức componentDidCatch trong React là gì?

Trả lời: Phương thức componentDidCatch được sử dụng để bắt các lỗi JavaScript trong cây component và ghi lại các lỗi đó, hiển thị UI dự phòng thay vì làm hỏng toàn bộ ứng dụng.

Ví dụ:

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  componentDidCatch(error, errorInfo) {
    this.setState({ hasError: true });
    console.error(error, errorInfo);
  }

  render() {
    if (this.state.hasError) {
      return <h1>Something went wrong.</h1>;
    }
    return this.props.children;
  }
}

27. Làm thế nào để bạn kết xuất các component có điều kiện trong React?

Trả lời: Bạn có thể kết xuất các component có điều kiện trong React bằng cách sử dụng các biểu thức JavaScript trong JSX hoặc bằng cách sử dụng kết xuất có điều kiện với câu lệnh if hoặc toán tử bậc ba.

Ví dụ:

function Greeting(props) {
  if (props.isLoggedIn) {
    return <h1>Welcome back!</h1>;
  }
  return <h1>Please sign up.</h1>;
}

28. Mục đích của phương thức shouldComponentUpdate là gì?

Trả lời: Phương thức shouldComponentUpdate được sử dụng để cho React biết liệu đầu ra của component có bị ảnh hưởng bởi sự thay đổi trong props hoặc state hay không, cho phép bạn ngăn chặn việc kết xuất lại không cần thiết.

Ví dụ:

class MyComponent extends React.Component {
  shouldComponentUpdate(nextProps, nextState) {
    return nextProps.value !== this.props.value;
  }

  render() {
    return <div>{this.props.value}</div>;
  }
}

29. Keys trong React là gì và tại sao chúng lại quan trọng?

Trả lời: Keys là các thuộc tính chuỗi đặc biệt được React sử dụng để xác định các mục đã thay đổi, được thêm hoặc bị xóa trong danh sách, giúp React tối ưu hóa hiệu suất kết xuất.

Ví dụ:

const items = ["Apple", "Banana", "Cherry"];
const listItems = items.map((item, index) => <li key={index}>{item}</li>);

30. Làm thế nào để bạn cập nhật trạng thái của một component trong React?

Trả lời: Bạn có thể cập nhật trạng thái của một component trong React bằng cách gọi phương thức setState và truyền cho nó một đối tượng với các giá trị trạng thái mới.

Ví dụ:

class Counter extends React.Component {
  constructor(props) {
    super(props);
    this.state = { count: 0 };
  }

  increment = () => {
    this.setState({ count: this.state.count + 1 });
  };

  render() {
    return (
      <div>
        <p>Count: {this.state.count}</p>
        <button onClick={this.increment}>Increment</button>
      </div>
    );
  }
}

31. Mục đích của phương thức getDerivedStateFromProps là gì?

Trả lời: Phương thức getDerivedStateFromProps là một phương thức tĩnh được sử dụng để cập nhật trạng thái của một component dựa trên các thay đổi trong props, trả về một đối tượng để cập nhật trạng thái hoặc null để cho biết không có thay đổi nào cần thiết.

Ví dụ:

class MyComponent extends React.Component {
  static getDerivedStateFromProps(nextProps, prevState) {
    if (nextProps.color !== prevState.color) {
      return { color: nextProps.color };
    }
    return null;
  }

  constructor(props) {
    super(props);
    this.state = { color: props.color };
  }

  render() {
    return <div style={{ color: this.state.color }}>Colored div</div>;
  }
}

32. Các phương thức vòng đời khác nhau trong React là gì?

Trả lời: Các phương thức vòng đời khác nhau trong React bao gồm:

  • Mounting Methods:
    • constructor
    • render
    • componentDidMount
  • Updating Methods:
    • render
    • getDerivedStateFromProps
    • shouldComponentUpdate
    • componentDidUpdate
  • Unmounting Methods:
    • componentWillUnmount

33. Mục đích của hàm React.memo là gì?

Trả lời: Hàm React.memo là một higher-order component ghi nhớ một component hàm, ngăn chặn việc kết xuất lại không cần thiết nếu các props của component không thay đổi.

Ví dụ:

const MyComponent = React.memo(function MyComponent(props) {
  /* render using props */
});

34. Làm thế nào để bạn xử lý lỗi trong React?

Trả lời: Bạn có thể xử lý lỗi trong React bằng cách sử dụng error boundaries, là các component đặc biệt bắt các lỗi JavaScript trong cây component con của chúng và hiển thị UI dự phòng thay vì làm hỏng toàn bộ ứng dụng.

Ví dụ:

const ErrorBoundary = ({ children }) => {
  const [hasError, setHasError] = React.useState(false);

  const static getDerivedStateFromError(error) {
    return { hasError: true };
  }

  componentDidCatch(error, errorInfo) {
    console.error(error, errorInfo);
  }

  if (hasError) {
    return <h1>Something went wrong.</h1>;
  }

  return children;
};

35. Mục đích của lớp PureComponent trong React là gì?

Trả lời: Lớp PureComponent là một component lớp thực hiện shouldComponentUpdate với so sánh nông props và state, ngăn chặn việc kết xuất lại không cần thiết nếu props và state của component không thay đổi.

Ví dụ:

class MyComponent extends React.PureComponent {
  render() {
    return <div>{this.props.value}</div>;
  }
}

36. Mục đích của thuộc tính dangerouslySetInnerHTML trong React là gì?

Trả lời: Thuộc tính dangerouslySetInnerHTML được sử dụng để đặt HTML trực tiếp từ React, bỏ qua bảo vệ XSS của React. Nó nên được sử dụng một cách thận trọng vì nó có thể làm cho ứng dụng của bạn dễ bị tấn công XSS.

Ví dụ:

const dangerousHtml = { __html: "<div>Content</div>" };

function MyComponent() {
  return <div dangerouslySetInnerHTML={dangerousHtml} />;
}

37. Sự khác biệt giữa createElementcloneElement trong React là gì?

Trả lời:

  • createElement: Được sử dụng để tạo một phần tử React mới. Nó có ba đối số chính: loại phần tử (một chuỗi cho các thẻ DOM hoặc một tham chiếu đến một component), props cho phần tử và các phần tử con.
  • cloneElement: Được sử dụng để sao chép một phần tử hiện có và truyền các props mới cho nó. Điều này rất hữu ích để sửa đổi hoặc mở rộng các props của một phần tử hiện có.

Ví dụ:

import React from "react";

// Sử dụng createElement
const element = React.createElement(
  "h1",
  { className: "greeting" },
  "Hello, React!"
);

// Sử dụng cloneElement
const clonedElement = React.cloneElement(element, { style: { color: "blue" } });

function App() {
  return (
    <div>
      {element}
      {clonedElement}
    </div>
  );
}

38. Mục đích của phương thức componentDidUpdate trong React là gì?

Trả lời: Phương thức componentDidUpdate được gọi sau khi các cập nhật của một component được đẩy vào DOM. Nó cho phép bạn thực hiện các side effect sau khi component đã được cập nhật, chẳng hạn như thực hiện các yêu cầu mạng dựa trên các props mới.

Ví dụ:

class MyComponent extends React.Component {
  componentDidUpdate(prevProps) {
    if (this.props.userID !== prevProps.userID) {
      this.fetchData(this.props.userID);
    }
  }

  fetchData(userID) {
    console.log(`Fetching data for user ${userID}`);
  }

  render() {
    return <div>User ID: {this.props.userID}</div>;
  }
}

39. Forward refs trong React là gì?

Trả lời: Forward refs cho phép bạn chuyển các refs thông qua một component đến các component con của nó. Điều này rất hữu ích khi bạn cần truy cập nút DOM hoặc phần tử React của một component con từ một component cha.

Ví dụ:

import React from "react";

const FancyButton = React.forwardRef((props, ref) => (
  <button ref={ref} className="FancyButton">
    {props.children}
  </button>
));

function App() {
  const ref = React.createRef();

  return (
    <div>
      <FancyButton ref={ref}>Click me!</FancyButton>
      <button onClick={() => alert(ref.current.textContent)}>
        Log Button Text
      </button>
    </div>
  );
}

40. Mục đích của phương thức static getDerivedStateFromError là gì?

Trả lời: Phương thức static getDerivedStateFromError được sử dụng để cập nhật trạng thái của một component khi một lỗi được ném ra trong một component con cháu. Nó cho phép component kết xuất UI dự phòng thay vì bị lỗi.

Ví dụ:

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error) {
    return { hasError: true };
  }

  componentDidCatch(error, errorInfo) {
    console.error(error, errorInfo);
  }

  render() {
    if (this.state.hasError) {
      return <h1>Something went wrong.</h1>;
    }

    return this.props.children;
  }
}

41. Mục đích của phương thức createRef trong React là gì?

Trả lời: Phương thức createRef được sử dụng để tạo một ref có thể được gắn vào một phần tử React hoặc một nút DOM. Nó cho phép bạn truy cập phần tử hoặc nút một cách bắt buộc.

Ví dụ:

import React from "react";

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.inputRef = React.createRef();
  }

  focusInput = () => {
    this.inputRef.current.focus();
  };

  render() {
    return (
      <div>
        <input ref={this.inputRef} />
        <button onClick={this.focusInput}>Focus Input</button>
      </div>
    );
  }
}

42. Mục đích của hook useContext trong React là gì?

Trả lời: Hook useContext được sử dụng để sử dụng React context trong một component hàm. Nó cho phép bạn truy cập giá trị context mà không cần phải sử dụng component lớp hoặc component consumer.

Ví dụ:

import React, { useContext, createContext } from "react";

const ThemeContext = createContext("light");

function ThemedButton() {
  const theme = useContext(ThemeContext);
  return <button style={{ background: theme }}>Button</button>;
}

function App() {
  return (
    <ThemeContext.Provider value="dark">
      <ThemedButton />
    </ThemeContext.Provider>
  );
}

43. Sự khác biệt giữa các hook useMemouseCallback trong React là gì?

Trả lời:

  • useMemo: Ghi nhớ một giá trị để ngăn các phép tính tốn kém trên mỗi lần kết xuất. Nó lưu kết quả vào bộ nhớ cache và trả về giá trị đã lưu trong bộ nhớ cache nếu các phụ thuộc không thay đổi.
  • useCallback: Ghi nhớ một hàm để ngăn chặn việc kết xuất lại không cần thiết của các component con. Nó lưu hàm vào bộ nhớ cache và trả về hàm đã lưu trong bộ nhớ cache nếu các phụ thuộc không thay đổi.

Ví dụ:

import React, { useMemo, useCallback, useState } from "react";

function App() {
  const [count, setCount] = useState(0);
  const [inputValue, setInputValue] = useState("");

  const expensiveValue = useMemo(() => {
    console.log("Calculating...");
    return count * 2;
  }, [count]);

  const handleChange = useCallback((event) => {
    setInputValue(event.target.value);
  }, []);

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
      <p>Expensive Value: {expensiveValue}</p>
      <input value={inputValue} onChange={handleChange} />
    </div>
  );
}

44. Mục đích của hook useReducer trong React là gì?

Trả lời: Hook useReducer được sử dụng để quản lý logic trạng thái phức tạp trong một component bằng cách sử dụng hàm reducer, tương tự như cách Redux quản lý trạng thái trong một ứng dụng. Nó đặc biệt hữu ích khi bạn có logic trạng thái liên quan đến nhiều giá trị phụ hoặc khi trạng thái tiếp theo phụ thuộc vào trạng thái trước đó.

Ví dụ:

import React, { useReducer } from "react";

const initialState = { count: 0 };

function reducer(state, action) {
  switch (action.type) {
    case "increment":
      return { count: state.count + 1 };
    case "decrement":
      return { count: state.count - 1 };
    default:
      throw new Error();
  }
}

function Counter() {
  const [state, dispatch] = useReducer(reducer, initialState);

  return (
    <div>
      <p>Count: {state.count}</p>
      <button onClick={() => dispatch({ type: "increment" })}>+</button>
      <button onClick={() => dispatch({ type: "decrement" })}>-</button>
    </div>
  );
}

45. Làm thế nào để bạn kiểm thử các component React?

Trả lời: Bạn có thể kiểm thử các component React bằng cách sử dụng các thư viện như Jest và React Testing Library, cung cấp các tiện ích để kết xuất các component, tương tác với chúng và khẳng định hành vi của chúng.

Ví dụ:

import React from "react";
import { render, screen, fireEvent } from "@testing-library/react";
import "@testing-library/jest-dom/extend-expect";
import Counter from "./Counter";

test("increments count", () => {
  render(<Counter />);
  const countText = screen.getByText(/count:/i);
  const incrementButton = screen.getByText(/\+/i);

  fireEvent.click(incrementButton);

  expect(countText).toHaveTextContent(/count: 1/i);
});

46. Mục đích của component React.StrictMode là gì?

Trả lời: Component React.StrictMode được sử dụng để làm nổi bật các vấn đề tiềm ẩn trong một ứng dụng React trong quá trình phát triển, chẳng hạn như các phương thức vòng đời không được dùng nữa và các phương thức vòng đời không an toàn. Nó giúp xác định và sửa chữa chúng sớm trong quá trình phát triển.

Ví dụ:

import React from "react";

function App() {
  return (
    <React.StrictMode>
      <div>
        <p>Hello, React!</p>
      </div>
    </React.StrictMode>
  );
}

47. Làm thế nào để bạn tích hợp các thư viện của bên thứ ba với React?

Trả lời: Bạn có thể tích hợp các thư viện của bên thứ ba với React bằng cách sử dụng trực tiếp chúng trong các component của bạn hoặc bằng cách tạo các component React tùy chỉnh bao bọc chức năng của thư viện bên thứ ba.

Ví dụ: Tích hợp thư viện biểu đồ của bên thứ ba như Chart.js:

import React, { useRef, useEffect } from "react";
import Chart from "chart.js/auto";

function ChartComponent() {
  const chartRef = useRef(null);

  useEffect(() => {
    const ctx = chartRef.current.getContext("2d");
    new Chart(ctx, {
      type: "bar",
      data: {
        labels: ["January", "February", "March"],
        datasets: [
          {
            label: "Monthly Sales",
            data: [50, 60, 70],
            backgroundColor: "rgba(54, 162, 235, 0.2)",
            borderColor: "rgba(54, 162, 235, 1)",
            borderWidth: 1,
          },
        ],
      },
      options: {
        scales: {
          y: {
            beginAtZero: true,
          },
        },
      },
    });
  }, []);

  return <canvas ref={chartRef} />;
}

export default ChartComponent;

48. Mục đích của hook useLayoutEffect trong React là gì?

Trả lời: Hook useLayoutEffect tương tự như useEffect nhưng kích hoạt đồng bộ sau tất cả các đột biến DOM, cho phép bạn thực hiện các hành động yêu cầu DOM phải được cập nhật trước khi tiếp tục.

Ví dụ: Đo kích thước của một phần tử DOM sau khi nó đã được kết xuất:

import React, { useLayoutEffect, useRef } from "react";

function MeasurementComponent() {
  const divRef = useRef(null);

  useLayoutEffect(() => {
    if (divRef.current) {
      console.log("Width:", divRef.current.offsetWidth);
      console.log("Height:", divRef.current.offsetHeight);
    }
  }, []);

  return <div ref={divRef}>Measure Me</div>;
}

export default MeasurementComponent;

49. Làm thế nào để bạn xử lý xác thực trong một ứng dụng React?

Trả lời: Bạn có thể xử lý xác thực trong một ứng dụng React bằng cách sử dụng các thư viện như Auth0 hoặc Firebase, lưu trữ mã thông báo trong bộ nhớ cục bộ hoặc cookie và bảo vệ các tuyến đường dựa trên trạng thái xác thực.

Ví dụ: Sử dụng Firebase để xác thực:

import React, { useState, useEffect } from "react";
import firebase from "firebase/app";
import "firebase/auth";
import { BrowserRouter, Route, Switch, Redirect } from "react-router-dom";

// Khởi tạo Firebase
firebase.initializeApp({
  apiKey: "YOUR_API_KEY",
  authDomain: "YOUR_AUTH_DOMAIN",
  projectId: "YOUR_PROJECT_ID",
  storageBucket: "YOUR_STORAGE_BUCKET",
  messagingSenderId: "YOUR_MESSAGING_SENDER_ID",
  appId: "YOUR_APP_ID",
});

function AuthProvider({ children }) {
  const [user, setUser] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const unsubscribe = firebase.auth().onAuthStateChanged((user) => {
      setUser(user);
      setLoading(false);
    });

    return () => unsubscribe();
  }, []);

  if (loading) {
    return <div>Loading...</div>;
  }

  return (
    <AuthContext.Provider value={{ user }}>{children}</AuthContext.Provider>
  );
}

const ProtectedRoute = ({ component: Component, ...rest }) => (
  <Route
    {...rest}
    render={(props) =>
      rest.authContext.user ? (
        <Component {...props} />
      ) : (
        <Redirect to="/login" />
      )
    }
  />
);

function App() {
  return (
    <AuthProvider>
      <BrowserRouter>
        <Switch>
          <ProtectedRoute path="/dashboard" component={Dashboard} />
          <Route path="/login" component={Login} />
        </Switch>
      </BrowserRouter>
    </AuthProvider>
  );
}

50. Một số phương pháp hay nhất để viết các component React là gì?

Trả lời:

  • Giữ các Component Nhỏ và Tập trung: Chia nhỏ các component lớn thành các component nhỏ hơn, có thể sử dụng lại.
  • Sử dụng các Component Hàm khi có thể: Các component hàm đơn giản hơn và dễ kiểm tra hơn.
  • Sử dụng Hooks cho Logic Trạng thái: Sử dụng các hook như useState, useEffectuseContext để quản lý trạng thái và các side effect trong các component hàm.
  • Tuân theo các Quy ước Đặt tên cho Props và Biến Trạng thái: Sử dụng tên rõ ràng và mô tả cho props và các biến trạng thái để cải thiện khả năng đọc và bảo trì.
  • Sử dụng Xử lý Lỗi Phù hợp: Sử dụng error boundaries để xử lý lỗi một cách duyên dáng.
  • Tối ưu hóa Hiệu suất Component: Sử dụng React.memo, useMemouseCallback để tối ưu hóa hiệu suất bằng cách ngăn chặn việc kết xuất lại không cần thiết.

Bằng cách nắm vững các khái niệm và phương pháp này, bạn sẽ chuẩn bị tốt cho các cuộc phỏng vấn React.js và có thể viết các ứng dụng React hiệu quả, dễ bảo trì và thân thiện với người dùng.