Danh sách câu hỏi của đề

Câu hỏi: FER202 Phát triển web Front-End với React – Bộ ôn tập cuối kỳ số 1

50 câu trắc nghiệm kèm lời giải của môn FER202 - Phát triển web Front-End với React, xếp đúng thứ tự trong đề. Trang 2/3 — câu 21–40.

Danh sách câu hỏi

40/50 câuCòn 10
AThey eliminate the need for HTML
BThey allow for faster development by providing pre-built components
CThey only work on mobile applications
DThey focus solely on server-side development
Lời giải
Đáp án đúng: "They allow for faster development by providing pre-built components". Framework hay thư viện front-end như React hoặc Vue.js cho phép chia giao diện thành các component (thành phần) tái sử dụng, có sẵn cơ chế quản lý state và cập nhật giao diện khi dữ liệu đổi, lại đi kèm hệ sinh thái component dựng sẵn, nên lập trình viên không phải tự viết lại từ đầu thao tác DOM cho từng nút, bảng hay biểu mẫu, từ đó phát triển nhanh hơn. "They eliminate the need for HTML" sai vì kết quả cuối cùng vẫn là HTML và DOM trong trình duyệt; JSX hay template của Vue chỉ là cách viết khác của chính các thẻ đó. "They only work on mobile applications" sai vì hai công cụ này chủ yếu chạy trên trình duyệt web; làm app di động cần thêm thư viện riêng như React Native. "They focus solely on server-side development" sai vì chúng là công cụ phía client, xử lý giao diện người dùng chứ không phải logic máy chủ.
Mở trang câu hỏi này →
AThe column will only have its width defined on extra-large screens.
BThe column will only have its width defined on extra-small screens, and larger sizes will ignore it
CThe column will have its width defined on extra-small screens and will apply to larger sizes if no specific breakpoint is defined.
DThe xs prop does not exist in React-Bootstrap
Lời giải
Đáp án đúng: "The column will have its width defined on extra-small screens and will apply to larger sizes if no specific breakpoint is defined.". React-Bootstrap dựng lưới theo hướng mobile-first (ưu tiên màn nhỏ) giống Bootstrap: prop xs trên Col sinh lớp cột áp dụng từ điểm ngắt nhỏ nhất trở lên, nên độ rộng đặt bằng xs giữ nguyên ở các màn sm, md, lg, xl cho tới khi gặp một prop điểm ngắt lớn hơn như md ghi đè. Ví dụ Col xs={6} chiếm nửa hàng trên mọi màn hình nếu không có prop điểm ngắt nào khác. Phương án "The column will only have its width defined on extra-large screens." nhầm xs với xl (extra-large). Phương án có mảnh "and larger sizes will ignore it" sai vì Bootstrap không giới hạn lớp theo kiểu chỉ áp cho màn nhỏ; lớp của điểm ngắt nhỏ được kế thừa lên mọi màn lớn hơn. Phương án "The xs prop does not exist in React-Bootstrap" sai vì Col có đủ các prop xs, sm, md, lg, xl, xxl.
Mở trang câu hỏi này →
AIt provides more flexibility to create custom designs and components.
BIt is easier to use and has fewer customization options.
CIt has predefined components for quick styling.
DIt offers faster page loading times.
Lời giải
Đáp án đúng: "It provides more flexibility to create custom designs and components.". Tailwind CSS là framework utility-first (ưu tiên lớp tiện ích): mỗi lớp như p-4, text-center hay bg-blue-500 chỉ làm một việc, người dùng tự ghép chúng thành giao diện riêng, nên không bị bó vào vẻ ngoài chung của các component dựng sẵn như ở Bootstrap. "It is easier to use and has fewer customization options." sai ở cả hai vế: Tailwind thường cần làm quen nhiều tên lớp hơn và lại cho tuỳ biến nhiều hơn qua tệp cấu hình theme. "It has predefined components for quick styling." là thế mạnh của Bootstrap với card, navbar, modal có sẵn, không phải của Tailwind. "It offers faster page loading times." không phải ưu điểm chính: Tailwind loại các lớp không dùng khi build nên tệp CSS gọn, nhưng tốc độ tải trang còn phụ thuộc nhiều yếu tố khác và Bootstrap cũng có thể được tối ưu.
Mở trang câu hỏi này →
ATriggering a render when state or props change.
BRe-rendering the component.
CCommitting the changes to the DOM.
DCalculating the minimal necessary updates for the DOM.
Lời giải
Đáp án đúng: "Triggering a render when state or props change.". Tài liệu React mô tả việc hiển thị giao diện qua ba bước: trigger (kích hoạt) một lần render, render component, rồi commit vào DOM. Một lần render chỉ bắt đầu khi có tác nhân kích hoạt: lần mount đầu tiên qua root.render, hoặc khi state của component hay của component cha (khiến props đổi) được cập nhật qua hàm set. "Re-rendering the component." là bước thứ hai: React gọi lại hàm component để lấy JSX mới, và nó chỉ xảy ra sau khi đã có tác nhân kích hoạt. "Calculating the minimal necessary updates for the DOM." là phần so sánh cây (reconciliation) diễn ra trong pha render, cũng đứng sau bước kích hoạt. "Committing the changes to the DOM." là bước cuối cùng, khi React mới thực sự chạm vào DOM thật.
Mở trang câu hỏi này →
ATo render React components faster
BTo manage component state globally
CTo make HTTP requests to APIs
DTo build reusable hooks
Lời giải
Đáp án đúng: "To make HTTP requests to APIs". Axios là thư viện HTTP client (máy khách HTTP) dựa trên Promise, chạy được cả trong trình duyệt lẫn Node.js; trong React nó thường được gọi trong useEffect hoặc hàm xử lý sự kiện để gửi GET, POST, PUT, DELETE tới API, tự chuyển dữ liệu JSON, và có interceptor (bộ chặn) để gắn token hay xử lý lỗi tập trung. "To render React components faster" không đúng vì Axios không can thiệp vào quá trình render, tốc độ render phụ thuộc React và các kỹ thuật như React.memo. "To manage component state globally" là việc của Redux hoặc Context, không phải Axios. "To build reusable hooks" là việc của custom hook; ta có thể viết một hook dùng Axios bên trong, nhưng bản thân Axios không phải công cụ để tạo hook.
Mở trang câu hỏi này →
AUtilize the <Switch> component to handle nested routes
BImplement a routing table using an array of route objects
CUse the <Route> component with nested <Route> components
DDirect routes using query parameters in URL path names
Lời giải

Đáp án đúng: "Use the <Route> component with nested <Route> components". Trong React Router v6, tuyến lồng nhau được khai báo bằng cách đặt các Route con bên trong một Route cha; path của Route con được nối tiếp vào path của cha, và component của Route cha đặt Outlet ở chỗ muốn hiển thị nội dung của tuyến con đang khớp. "Utilize the <Switch> component to handle nested routes" sai vì Switch là component của React Router v5 và đã bị thay bằng Routes ở v6; hơn nữa Switch chỉ chọn tuyến đầu tiên khớp chứ không tự tạo cấu trúc lồng. "Implement a routing table using an array of route objects" chỉ đúng trong hoàn cảnh khác: v6 cho khai báo mảng đối tượng có thuộc tính children qua useRoutes hoặc createBrowserRouter, nhưng câu hỏi hỏi cách định nghĩa cấu trúc lồng bên trong component cha bằng JSX, và cách được dạy là Route lồng Route. "Direct routes using query parameters in URL path names" sai vì query string (phần sau dấu ?) chỉ mang dữ liệu đọc bằng useSearchParams, không tham gia khớp tuyến nên không tạo được cấu trúc lồng.

Mở trang câu hỏi này →
ATo enable server-side rendering and generate static websites.
BTo manage state in React applications.
CTo provide a UI component library.
DTo create database schemas.
Lời giải
Đáp án đúng: "To enable server-side rendering and generate static websites.". Next.js là framework xây trên React, bổ sung những thứ React thuần không có sẵn: server-side rendering (SSR, dựng HTML trên máy chủ cho mỗi request), static site generation (SSG, sinh trang tĩnh lúc build), định tuyến theo cấu trúc thư mục và API route; nhờ HTML có sẵn khi tải trang, trang hiển thị nhanh hơn và thân thiện với SEO. "To manage state in React applications." sai vì quản lý state là việc của useState, Context hay thư viện như Redux Toolkit, không phải mục đích chính của Next.js. "To provide a UI component library." sai vì Next.js không cung cấp bộ nút, thẻ hay bảng dựng sẵn như React-Bootstrap hoặc MUI. "To create database schemas." sai vì thiết kế lược đồ cơ sở dữ liệu thuộc về công cụ ORM như Prisma hoặc chính hệ quản trị cơ sở dữ liệu.
Mở trang câu hỏi này →
AIncluding all state variables in the dependency array.
BNot using a dependency array.
CIncluding a variable like data that changes often in the dependency array.
DOmitting the dependency array altogether.
Lời giải
Đáp án đúng: "Including a variable like data that changes often in the dependency array.". Effect chạy sau lần render đầu và chạy lại mỗi khi một giá trị trong mảng phụ thuộc (dependency array) khác giá trị ở lần render trước theo phép so sánh Object.is; nếu đưa vào mảng một biến như data thay đổi liên tục (dữ liệu mới sau mỗi lần tải, hoặc đối tượng, mảng tạo mới ở mỗi render), Effect sẽ chạy lại liên tục, thậm chí thành vòng lặp nếu chính Effect cập nhật data. Cần nói thẳng: "Not using a dependency array." và "Omitting the dependency array altogether." cũng khiến Effect chạy sau mọi lần render, tức cũng là chạy quá thường xuyên; nhưng hai phương án này diễn đạt cùng một ý nên không thể cùng là đáp án duy nhất của câu chọn một, và đáp án được chọn là tình huống biến hay đổi nằm trong mảng. Phương án "Including all state variables in the dependency array." tự nó không phải nguyên nhân đặc trưng: khai báo đủ các state mà Effect dùng là điều React yêu cầu, và Effect chỉ chạy lại khi các state đó thật sự đổi.
Mở trang câu hỏi này →
Aconst { userId, postId } = useParams();
Bconst userId = useParams('userId'); const postId = useParams('postId');
Cconst userId = route.params.userId; const postId = route.params.postId;
Dconst { userId } = useParams(); const { postId } = useParams();
Lời giải
Đáp án đúng: "const { userId, postId } = useParams();". Hook useParams của React Router v6 không nhận đối số và trả về một đối tượng chứa mọi tham số động của đường dẫn đang khớp; với route /users/:userId/posts/:postId, đối tượng đó có hai khoá userId và postId, phép destructuring (phân rã) lấy cả hai trong một lần gọi, sau đó hiển thị bằng {userId} và {postId} trong JSX. "const userId = useParams('userId'); const postId = useParams('postId');" sai vì useParams không nhận tên tham số, đối số truyền vào bị bỏ qua nên mỗi biến nhận cả đối tượng chứ không phải một chuỗi. "const userId = route.params.userId; const postId = route.params.postId;" là cách đọc tham số của React Navigation trên React Native; trong React Router không có biến route nào như vậy. "const { userId } = useParams(); const { postId } = useParams();" chạy được và cho đúng giá trị, nhưng gọi hook hai lần để lấy hai khoá từ cùng một đối tượng là thừa, không phải cách gọn được hỏi.
Mở trang câu hỏi này →
A<Container> <Row> <Col>1 of 3</Col> <Col>2 of 3</Col> <Col>3 of 3</Col> </Row> </Container>
B<Container> <Row> <Col sm={4}>1 of 3</Col> <Col sm={4}>2 of 3</Col> <Col sm={4}>3 of 3</Col> </Row> </Container>
C<Container> <Row> <Col md={12}>1 of 4</Col> <Col md={12}>2 of 4</Col> <Col md={12}>3 of 4</Col> </Row> </Container>
D<Container> <Row> <Col sm={12} md={4}>1 of 4</Col> <Col sm={12} md={4}>2 of 4</Col> <Col sm={12} md={4}>3 of 4</Col> </Row> </Container>
Lời giải

Đáp án đúng: "

Lời giải
<Container> <Row> <Col sm={
  12
}
md={
  4
}
>1 of 4</Col> <Col sm={
  12
}
md={
  4
}
>2 of 4</Col> <Col sm={
  12
}
md={
  4
}
>3 of 4</Col> </Row> </Container>

". Grid của React-Bootstrap theo mobile-first: sm={12} nghĩa là từ breakpoint sm (576px) mỗi cột chiếm đủ 12/12 phần nên ba cột xếp chồng dọc, còn md={4} nghĩa là từ md (768px) mỗi cột chiếm 4/12 nên ba cột nằm ngang trên một hàng; dưới 576px, Col không khai báo xs cũng rộng hết hàng. Như vậy ba cột xếp dọc trên màn nhỏ và thành ba cột trên màn vừa trở lên. Phải nói thẳng: phương án chứa "

Lời giải
<Col sm={
  4
}
>1 of 3</Col>

" cũng xếp dọc nếu màn nhỏ được hiểu là dưới 576px, nhưng nó cho ba cột nằm ngang ngay từ mốc sm nên không giữ được bố cục dọc ở màn sm mà câu hỏi nhắm tới. Phương án chứa "<Col>1 of 3</Col> " để Col tự chia đều, ba cột luôn nằm ngang ở mọi kích thước. Phương án chứa "

Lời giải
<Col md={
  12
}
>1 of 4</Col>

" cho mỗi cột rộng đủ hàng ở mọi kích thước nên luôn xếp dọc, kể cả màn lớn. Chữ 1 of 4 bên trong Col chỉ là nội dung hiển thị đánh số lệch, không ảnh hưởng bố cục.

Mở trang câu hỏi này →
A.form-control
B.input-group
C.form-check
D.form-validation
Lời giải
Đáp án đúng: ".form-control". Trong Bootstrap 5, ô nhập văn bản được tạo bằng lớp .form-control, và trạng thái kiểm tra hợp lệ (validation) hiện ngay trên chính ô này khi thêm .is-valid hoặc .is-invalid, hoặc khi form mang .was-validated, kèm khối .valid-feedback, .invalid-feedback để hiện thông báo; vì vậy .form-control là lớp nền để có một input mang trạng thái validation. ".input-group" chỉ gom input với nút hoặc nhãn phụ thành một cụm, không tạo trạng thái hợp lệ. ".form-check" dùng cho checkbox và radio, không phải ô nhập văn bản thông thường. ".form-validation" không phải lớp có sẵn của Bootstrap 5; các lớp validation thật có tên is-valid, is-invalid, was-validated và needs-validation.
Mở trang câu hỏi này →
AWebSockets
BuseState()
Cfetch() or axios inside useEffect()
Dconsole.log() inside render()
Lời giải
Đáp án đúng: "fetch() or axios inside useEffect()". Lấy dữ liệu từ máy chủ là một side effect (tác dụng phụ), nên trong component hàm nó được đặt trong useEffect: effect chạy sau khi component đã render và hiển thị, gọi fetch hoặc axios, rồi khi Promise trả kết quả thì gọi hàm set của useState để lưu dữ liệu và kích hoạt render lại; mảng phụ thuộc rỗng khiến việc gọi chỉ diễn ra một lần sau lần mount đầu tiên. "WebSockets" sai vì đó là kênh kết nối hai chiều giữ mở liên tục, dùng cho dữ liệu thời gian thực như chat hay thông báo, không phải cách thông dụng để tải dữ liệu theo kiểu hỏi một lần đáp một lần. "useState()" sai vì hook này chỉ lưu dữ liệu sau khi đã có, bản thân nó không gửi request nào. "console.log() inside render()" sai vì console.log chỉ in ra bảng điều khiển của trình duyệt để gỡ lỗi, không liên quan gì tới việc lấy dữ liệu.
Mở trang câu hỏi này →
Anpx create-react-app
Bnpm install next
Cnpx create-next-app
Dgit clone next.js
Lời giải
Đáp án đúng: "npx create-next-app". Lệnh này dùng npx để tải và chạy công cụ khởi tạo chính thức của Next.js mà không cần cài toàn cục; nó hỏi vài lựa chọn như TypeScript, ESLint, Tailwind, App Router rồi dựng sẵn thư mục dự án, tệp cấu hình, package.json và các script dev, build, start. "npx create-react-app" sai vì đó là công cụ tạo dự án React thuần chạy hoàn toàn phía client, không có SSR hay định tuyến theo thư mục của Next.js, và nay đã ngừng được khuyên dùng. "npm install next" sai vì chỉ cài gói next vào một dự án có sẵn, không dựng khung thư mục hay cấu hình nào, nên chưa tạo ra dự án mới. "git clone next.js" sai vì đây không phải lệnh hợp lệ để tạo dự án; nếu có clone thì cũng chỉ lấy về mã nguồn của chính framework chứ không phải một ứng dụng mới.
Mở trang câu hỏi này →
AReal-time data fetching.
BClient-side routing.
CAutomatic code splitting.
DServer-side rendering.
Lời giải
Đáp án đúng: "Server-side rendering.". Công cụ tìm kiếm đọc trang tốt nhất khi HTML trả về đã chứa sẵn nội dung; với render phía máy chủ (server-side rendering, SSR), Next.js chạy component React trên server ở mỗi request và gửi về trang HTML hoàn chỉnh kèm tiêu đề, thẻ meta, nên bot thu thập được nội dung ngay mà không phải chạy JavaScript, đó là lý do SSR (cùng với sinh trang tĩnh) được coi là tính năng cốt lõi giúp SEO. Phương án "Real-time data fetching." là chuyện cập nhật dữ liệu tức thời phía client, không làm HTML ban đầu giàu nội dung hơn. Phương án "Client-side routing." giúp chuyển trang nhanh trong trình duyệt, nhưng chính kiểu ứng dụng chỉ render phía client là thứ gây khó cho SEO. Phương án "Automatic code splitting." là tính năng có thật của Next.js, cắt mã theo trang để tải nhanh hơn, tốt cho hiệu năng nhưng không phải tính năng phục vụ SEO mà câu hỏi nhắm tới.
Mở trang câu hỏi này →
ATo build React components using jQuery
BTo use Bootstrap styles with inline CSS only
CTo provide Bootstrap-styled components built entirely with React
DTo convert Bootstrap HTML into Angular components
Lời giải
Đáp án đúng: "To provide Bootstrap-styled components built entirely with React". React-Bootstrap viết lại các thành phần của Bootstrap như Button, Modal, Navbar, Dropdown thành component React thật: vẫn dùng CSS của Bootstrap, nhưng phần JavaScript vốn dựa trên jQuery được thay bằng state và props của React, nên không có mã nào sửa DOM ngoài tầm kiểm soát của React. "To build React components using jQuery" ngược với mục tiêu của thư viện, vì nó ra đời chính để bỏ phụ thuộc jQuery. "To use Bootstrap styles with inline CSS only" sai vì React-Bootstrap dùng các lớp CSS của Bootstrap như btn, card, container chứ không chuyển sang CSS nội tuyến. "To convert Bootstrap HTML into Angular components" nhầm sang hệ khác: Angular có thư viện riêng như ng-bootstrap, còn React-Bootstrap chỉ phục vụ ứng dụng React.
Mở trang câu hỏi này →
Đề bài
server.use(router);
server.listen(port, () => {
  console.log('JSON server is running on port ${port}');
}

); What is the above code used for?

ACreate a dynamic server to serve JSON data.
BCreate a dynamic web application using JSON data.
CCreate a JSON file based on data from the server.
DConfigure the development environment for the project using JSON.
Lời giải
Đáp án đúng: "Create a dynamic server to serve JSON data.". Đoạn mã gọi jsonServer.create() để tạo một server Express, jsonServer.router('data.json') sinh tự động các route REST (GET, POST, PUT, PATCH, DELETE) từ các khoá trong tệp data.json, server.use(router) gắn bộ định tuyến đó vào server, rồi server.listen lắng nghe ở cổng 3000. Kết quả là một API giả lập trả dữ liệu JSON và ghi thay đổi ngược vào tệp, thường dùng làm backend tạm cho front-end khi phát triển. Chi tiết nhỏ: chuỗi trong console.log dùng nháy đơn nên in nguyên văn ${port} thay vì số cổng, muốn chèn biến phải dùng template literal; điều này không đổi mục đích của đoạn mã. "Create a dynamic web application using JSON data." sai vì mã không dựng giao diện hay ứng dụng web nào, chỉ dựng server dữ liệu. "Create a JSON file based on data from the server." đảo chiều: tệp data.json là nguồn, server đọc từ nó. "Configure the development environment for the project using JSON." sai vì không có cấu hình môi trường nào, mã chỉ khởi chạy một server.
Mở trang câu hỏi này →
AReact
BAngular
CDjango
DVue.js
Lời giải
Đáp án đúng: "Django". Django là framework web phía máy chủ (back-end) viết bằng Python, lo định tuyến, ORM truy cập cơ sở dữ liệu và sinh HTML trên server, nên không thuộc nhóm framework front-end chạy trong trình duyệt. Câu hỏi dạng phủ định nên phải chọn cái KHÔNG phải front-end; những cái tên đều là công cụ front-end thật thì không được chọn. "React" là thư viện JavaScript của Meta để xây giao diện bằng component, thường được xếp chung nhóm framework front-end phổ biến. "Angular" là framework front-end đầy đủ của Google viết bằng TypeScript, có sẵn router, form và dependency injection. "Vue.js" là framework front-end tăng tiến (progressive), dùng template và hệ phản ứng (reactivity) để tự cập nhật giao diện khi dữ liệu đổi.
Mở trang câu hỏi này →
ABecause it results in multiple HTTP requests, slowing down the application.
BBecause it decreases the performance by loading everything upfront.
CBecause it makes the code difficult to debug.
DBecause it affects the layout and styling of components.
Lời giải
Đáp án đúng: "Because it results in multiple HTTP requests, slowing down the application.". React.lazy tách mỗi component thành một chunk (gói mã) riêng, chỉ được tải về khi component đó cần hiển thị lần đầu. Nếu tách quá vụn, ứng dụng phải gửi rất nhiều request nhỏ, mỗi request có chi phí kết nối và độ trễ riêng, lại hay xảy ra kiểu tải nối đuôi khi component lười nằm trong component lười khác, nên người dùng thấy fallback liên tục và tổng thời gian chậm hơn. "Because it decreases the performance by loading everything upfront." sai vì nó mô tả ngược lại: lazy loading chính là để không tải mọi thứ ngay từ đầu. "Because it makes the code difficult to debug." không phải lý do chính, vì component lười vẫn gỡ lỗi bình thường qua source map và React DevTools. "Because it affects the layout and styling of components." sai vì lazy chỉ quyết định thời điểm tải mã JavaScript, không thay đổi CSS hay bố cục của component sau khi đã hiển thị.
Mở trang câu hỏi này →
39Why might this code produce unexpected results?4 lựa chọncó code
Đề bài
function Counter() {
  const [count, setCount] = useState(0);
  const handleClick = () => {
    setCount(count + 1);
    setCount(count + 1);
  };
  return <button onClick={handleClick}>{count}</button>;
}
ABecause setCount is called twice, it resets state
BBecause setCount merges the updates automatically
CBoth setCount(count + 1) calls use the same snapshot of count
DIt's invalid to call setCount twice
Lời giải
Đáp án đúng: "Both setCount(count + 1) calls use the same snapshot of count". Mỗi lần render, component Counter nhận một giá trị count cố định như ảnh chụp (snapshot); hàm handleClick được tạo trong lần render đó nên đóng gói (closure) đúng giá trị ấy. Khi count đang là 0, cả hai lời gọi đều tính 0 + 1 và cùng xếp vào hàng đợi yêu cầu đặt state thành 1, nên sau lần render kế tiếp nút hiện 1 chứ không phải 2 như người viết mong đợi; muốn cộng hai lần phải dùng hàm cập nhật dạng setCount(c => c + 1) để mỗi lần nhận giá trị mới nhất. "Because setCount is called twice, it resets state" sai vì không có gì bị đặt lại về 0, state chỉ lên 1. "Because setCount merges the updates automatically" sai vì React gom (batch) nhiều lần cập nhật vào một lần render nhưng không cộng dồn giá trị; trộn object là hành vi của this.setState trong class component. "It's invalid to call setCount twice" sai vì gọi hàm đặt state nhiều lần trong một sự kiện là hoàn toàn hợp lệ.
Mở trang câu hỏi này →
ABy passing an empty array as the second argument
BBy using a class-based component
CBy calling it after every render
DBy manually removing event listeners
Lời giải
Đáp án đúng: "By manually removing event listeners". Theo tài liệu React, Effect dọn dẹp bằng cách trả về một hàm cleanup; React gọi hàm này trước mỗi lần Effect chạy lại và khi component unmount, và việc cần làm bên trong là gỡ đúng thứ Effect đã gắn, ví dụ gọi removeEventListener cho listener đã thêm bằng addEventListener, hủy timer hay ngắt kết nối. Cách chuẩn nhất là trả về một hàm cleanup trong đó gỡ listener, nhưng câu không có phương án ấy, nên gỡ listener thủ công là phương án gần nhất với việc dọn dẹp thật sự. Phương án "By passing an empty array as the second argument" hay bị chọn nhầm: mảng phụ thuộc rỗng chỉ quyết định Effect chạy một lần lúc mount và cleanup chạy lúc unmount, tức quyết định thời điểm, còn bản thân nó không dọn dẹp gì; thiếu hàm cleanup thì listener vẫn rò rỉ. Phương án "By using a class-based component" đi ngược hướng hook, vì class dọn dẹp trong componentWillUnmount chứ không dùng useEffect. Phương án "By calling it after every render" là hành vi mặc định khi bỏ mảng phụ thuộc, làm Effect và cleanup chạy dày hơn chứ không tối ưu gì.
Mở trang câu hỏi này →