+1

Phiên điều trần luận tội Reactjs gây rối thế giới web app

Phiên Điều Trần Developer JavaScript Năm 2026

Cảnh: Phòng điều trần kỹ thuật số, với các developer từ khắp nơi trên thế giới tham dự qua Zoom. Thẩm phán là một Senior Full-Stack Dev trung lập. Công tố viên là một Senior JS Dev cay cú với React. Bị cáo React.js được đại diện bởi Middle React Developer – một dev vẫn trung thành nhưng không mù quáng. Buổi điều trần nhằm "luận tội" React.js vì gây khó khăn cho thế giới web app.

Thẩm phán: Chào mừng mọi người đến với phiên điều trần về React.js. Công tố viên, ông có 16 cáo trạng. Hãy bắt đầu. Sau mỗi cáo trạng, bên bào chữa sẽ phản biện. Chúng ta sẽ giữ trật tự và tập trung vào lập luận kỹ thuật.

1. Quản Lý Dependency Array

Công tố viên: Tại sao React lại bắt developer phải nhớ và quản lý dependency array thủ công cho các hooks như useEffect, dẫn đến dễ gây lỗi loop vô tận, trong khi các framework khác tự động theo dõi thay đổi?

Middle React Developer (Bào chữa): Thưa tòa, cách tiếp cận này của React nhấn mạnh vào sự explicitness, nghĩa là developer phải chỉ rõ ràng các dependency để tránh những hành vi ẩn giấu và khó dự đoán. Ví dụ, trong Vue hay Solid, tracking tự động có thể tiện lợi ban đầu nhưng khi xảy ra lỗi (như stale data hoặc unexpected re-runs), việc debug trở nên phức tạp vì không biết chính xác dependency nào đang hoạt động. Trade-off ở đây là giữa tính rõ ràng (dễ debug, dễ hiểu code) và tính tiện lợi (ít code hơn), và React chọn explicit để giúp các dự án lớn hơn duy trì được lâu dài mà không gặp "black magic" bất ngờ.

2. Re-Render Không Cần Thiết

Công tố viên: Tại sao React lại làm component chạy lại nhiều lần chỉ vì thay đổi nhỏ ở parent, dẫn đến tốn tài nguyên máy tính nghiêm trọng?

Middle React Developer: Không phải lỗi cốt lõi của React, mà thường do developer chưa áp dụng các kỹ thuật tối ưu hóa như React.memo để ngăn chặn re-render không cần thiết, hoặc useMemo/useCallback để cache giá trị và hàm. Từ phiên bản React 18 trở đi, các tính năng như useTransition và useDeferredValue cho phép hoãn các cập nhật không khẩn cấp, giúp app vẫn mượt mà ngay cả với dữ liệu lớn. Trong thực tế, nhiều ứng dụng lớn như Facebook hay Netflix sử dụng React mà vẫn đạt hiệu suất cao nhờ công cụ đo lường như React Profiler, chứng tỏ vấn đề nằm ở cách thiết kế code chứ không phải framework tự thân.

3. Quy Tắc Hooks Phản Trực Giác

Công tố viên: Tại sao quy tắc hooks chỉ gọi ở top level lại khó hiểu và dễ vi phạm đến vậy, khiến developer mới thường bối rối?

Middle React Developer: Quy tắc này được thiết kế để đảm bảo rằng các hooks luôn được gọi theo thứ tự cố định trong mỗi lần render, giúp React nội bộ quản lý state và effect một cách nhất quán mà không cần thêm overhead. Nếu cho phép gọi hooks có điều kiện (conditional), nó sẽ phá vỡ mental model của React, dẫn đến lỗi như state mismatch hoặc hooks bị bỏ qua. Trong thực tế, ESLint plugin của React giúp phát hiện vi phạm sớm, và sau khi quen, developer thấy nó giống như quy tắc "không mutate state trực tiếp" – ban đầu khó nhưng giúp code ổn định và dễ maintain hơn lâu dài.

4. Phân Chia Server Và Client

Công tố viên: Tại sao Server Components và Client Components lại làm code bị chia đôi, buộc developer phải nhớ hai môi trường khác nhau và tăng độ phức tạp tổng thể?

Middle React Developer: Đây là một bước tiến lớn về performance, vì Server Components cho phép chạy logic nặng ở server, giảm kích thước bundle JS gửi đến client và cải thiện thời gian tải ban đầu. Việc sử dụng 'use client' và 'use server' giúp phân biệt rõ ràng, tránh lỗi như gọi browser API ở server. Nhiều team sau 6-12 tháng làm quen đã thấy lợi ích, tương tự như sự chuyển dịch từ client-side rendering (CSR) sang server-side rendering (SSR) trước đây – ban đầu lạ lẫm nhưng cuối cùng giúp app nhanh hơn, SEO tốt hơn, và tiết kiệm tài nguyên client-side cho các thiết bị yếu.

5. Cleanup Trong Strict Mode

Công tố viên: Tại sao cleanup của useEffect lại không ổn định ở Strict Mode, buộc developer phải viết code xử lý trường hợp mount hai lần?

Middle React Developer: Đây thực chất là một tính năng hữu ích trong dev mode để mô phỏng hành vi thực tế như component remount do lỗi hoặc thay đổi state, giúp phát hiện sớm các vấn đề như race-condition hoặc leak memory. Ở production, double invoke không xảy ra, nên code vẫn chạy bình thường. Ví dụ, nếu bạn có subscription trong useEffect, Strict Mode sẽ buộc bạn viết cleanup đúng cách để tránh duplicate subscription – điều này "làm khó" ở dev nhưng ngăn chặn bug nghiêm trọng ở production, cuối cùng nâng cao chất lượng code tổng thể.

6. Context Gây Re-Render Lớn

Công tố viên: Tại sao Context lại làm re-render toàn bộ cây component con, trở thành nguyên nhân chính gây chậm ở app lớn?

Middle React Developer: Đúng là nếu lạm dụng Context cho mọi thứ, nó sẽ gây re-render lan rộng vì Context Provider thay đổi sẽ trigger tất cả consumer. Tuy nhiên, giải pháp là chia nhỏ Context thành các phần riêng biệt (ví dụ: một cho theme, một cho user data), hoặc sử dụng thư viện như use-context-selector để chỉ re-render component cần thiết. Context không được thiết kế để thay thế global state manager như Redux hay Zustand; khi dùng đúng, nó rất hiệu quả cho prop drilling mà không cần thêm thư viện phức tạp.

7. Tính Năng Mới Chưa Ổn Định

Công tố viên: Tại sao các tính năng mới như actions lại còn chưa hoàn thiện, với tài liệu mơ hồ và đầy trường hợp lỗi?

Middle React Developer: Đây là giai đoạn chuyển tiếp tự nhiên trong quá trình phát triển, nhưng so với cách xử lý form cũ (kết hợp controlled/uncontrolled components thủ công), actions mang lại cách tiếp cận đơn giản hơn với form submission và error handling tích hợp. Tài liệu sẽ cải thiện theo thời gian, và trong 1-2 năm tới, nó sẽ ổn định giống như hooks đã làm thay đổi React từ class components. Nhiều developer đã áp dụng thành công trong Next.js, chứng tỏ lợi ích vượt trội hơn nhược điểm tạm thời.

8. Kích Thước Bundle Lớn

Công tố viên: Tại sao kích thước React bundle vẫn lớn so với framework khác, dẫn đến app tải chậm hơn?

Middle React Developer: Đúng là React + ReactDOM có kích thước cơ bản lớn hơn một chút (khoảng 45-50kB gzipped), nhưng với các kỹ thuật như code-splitting (sử dụng dynamic import), lazy loading components, và đặc biệt Server Components, lượng JS thực tế gửi đến client có thể giảm xuống chỉ 10-20kB ở các app hiện đại năm 2025. So với Solid hay Svelte, React ưu tiên tính linh hoạt và hệ sinh thái lớn, giúp developer xây dựng app phức tạp mà không cần viết lại từ đầu.

9. Hứa Hẹn Chưa Thực Hiện

Công tố viên: Tại sao các tính năng như auto memo lại hứa hẹn lâu nhưng vẫn chưa ra mắt chính thức?

Middle React Developer: Việc phát triển một compiler như React Forget rất phức tạp, đặc biệt khi phải xử lý hooks và đảm bảo tương thích ngược mà không phá vỡ hàng triệu codebase hiện tại. Team React luôn ưu tiên stability và testing kỹ lưỡng thay vì ra mắt vội vã, tránh lặp lại sai lầm như các framework khác từng gặp. Trong khi chờ đợi, developer có thể dùng các polyfill hoặc thư viện bên thứ ba để đạt hiệu quả tương tự, và khi ra mắt, nó sẽ là game-changer cho performance.

10. Lạm Dụng Custom Hooks

Công tố viên: Tại sao custom hooks lại dễ dẫn đến code rối loạn, với nhiều lớp lồng nhau khó theo dõi?

Middle React Developer: Đây là vấn đề code smell từ cách sử dụng chứ không phải lỗi của React – custom hooks được thiết kế để tái sử dụng logic, nhưng nếu nhồi nhét quá nhiều vào một hook, nó sẽ trở nên phức tạp. Giải pháp là tách logic thành các hàm thuần (composable functions) hoặc services riêng biệt, chỉ dùng hooks cho phần liên quan đến React lifecycle. Khi làm đúng, custom hooks làm code sạch hơn, dễ test hơn, và giảm lặp code so với class components cũ.

11. Concurrent Và Suspense Phức Tạp

Công tố viên: Tại sao Concurrent Mode và Suspense lại làm code phức tạp hơn khi xử lý data?

Middle React Developer: Chúng thực sự làm code phức tạp hơn ban đầu, nhưng mang lại lợi ích lớn như loading state tự nhiên qua streaming, tránh waterfall fetching và giảm boilerplate cho loading/error handling thủ công. Ví dụ, thay vì viết if-else cho loading ở mọi nơi, Suspense cho phép wrap component và để React xử lý. Trong app lớn, điều này cải thiện UX với transitions mượt mà, và khi quen, developer thấy nó đơn giản hóa flow data fetching so với promise chain cũ.

12. Thay Đổi Hướng Thường Xuyên

Công tố viên: Tại sao React lại thay đổi hướng phát triển nhiều lần, buộc developer phải cập nhật code liên tục?

Middle React Developer: React phát triển theo nhu cầu thực tế, từ class sang hooks để đơn giản hóa state, rồi concurrent để cải thiện performance, và server/actions để hỗ trợ full-stack. Hầu hết thay đổi đều backward compatible (ví dụ: class components vẫn chạy tốt), cho phép migrate dần dần mà không cần rewrite toàn bộ. Điều này giữ React cạnh tranh và tiến bộ, khác với các framework ít thay đổi nhưng dễ bị lỗi thời.

13. Lỗi Hydration Phổ Biến

Công tố viên: Tại sao lỗi hydration lại xảy ra thường xuyên và khó debug ở app server-rendered?

Middle React Developer: Lỗi này thường do mismatch giữa HTML render ở server và client (như date random hoặc browser API), nhưng các phiên bản mới như Next.js 14+ và React 19 đã thêm công cụ như partial hydration và error boundaries để fix root cause. Developer có thể tránh bằng cách dùng useId cho unique keys hoặc defer client-only code, và công cụ debug như React DevTools giúp phát hiện nhanh chóng.

14. Hiệu Suất State Quản Lý

Công tố viên: Tại sao cách quản lý state như useReducer lại kém hiệu quả so với framework khác?

Middle React Developer: Ở app phức tạp, useReducer + Context có thể kém fine-grained reactivity, nhưng hệ sinh thái React cung cấp thay thế như Zustand, Jotai hay nanostores với signals-based approach, đạt hiệu suất tương đương hoặc tốt hơn. React không ép dùng built-in; sự linh hoạt này cho phép chọn tool phù hợp, giúp app scale mà không bị lock-in.

15. Giới Hạn Kỹ Năng Developer

Công tố viên: Tại sao React lại làm developer chỉ biết React thay vì JavaScript cơ bản, hạn chế kỹ năng tổng quát?

Middle React Developer: Developer giỏi React thường phải nắm vững JS core như closures, event loop, async/await vì hooks dựa trên đó. React chỉ là layer abstraction; ai chỉ học surface-level thì tự hạn chế mình, không phải lỗi framework. Ngược lại, React khuyến khích học sâu JS qua thực tế, và nhiều dev từ React dễ chuyển sang framework khác nhờ nền tảng vững.

16. Lỗi Bảo Mật Và Update Liên Tục

Công tố viên: Tại sao React lại có nhiều lỗi bảo mật xảy ra và phải xuất hiện nhiều bản update liên tục, làm developer mệt mỏi theo dõi?

Middle React Developer: Lỗi bảo mật thường xuất phát từ cách implement sai của developer (như không escape input dẫn đến XSS), chứ core React rất an toàn với built-in như dangerouslySetInnerHTML cảnh báo. Updates liên tục là để vá lỗ hổng nhanh chóng và thêm tính năng bảo mật mới (như automatic batching), hầu hết tương thích ngược nên không bắt buộc update ngay lập tức. So với framework ít update, React giúp app an toàn hơn lâu dài, và công cụ như Dependabot tự động hóa việc theo dõi.

Thẩm phán: Cảm ơn cả hai bên. Phiên điều trần kết thúc. React không vô tội, nhưng cũng không phải kẻ thù. Nó là công cụ mạnh mẽ với complexity đi kèm. Chúng ta sẽ tiếp tục theo dõi sự phát triển của nó. Buổi điều trần tạm hoãn.


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí