2 điểm bởi GN⁺ 2024-12-06 | 1 bình luận | Chia sẻ qua WhatsApp

19.0.0 (ngày 5 tháng 12 năm 2024)

Tính năng mới

React
  • Actions: startTransition giờ có thể chấp nhận các hàm bất đồng bộ. Các hàm này được gọi là "Actions", cập nhật trạng thái ở nền và commit UI trong một lần. Actions có thể thực hiện các side effect như yêu cầu bất đồng bộ, và sẽ chờ công việc hoàn tất trước khi Transition kết thúc.
  • useActionState: Hook mới cho phép sắp xếp Actions trong Transition và truy cập trạng thái. Nhận trạng thái ban đầu và reducer.
  • useOptimistic: Hook mới để cập nhật trạng thái trong khi Transition đang diễn ra. Khi Transition hoàn tất, trạng thái sẽ được cập nhật thành giá trị mới.
  • use: API mới để đọc tài nguyên trong lúc render. Chấp nhận Promise hoặc Context; nếu cung cấp Promise, quá trình sẽ bị tạm dừng cho đến khi giá trị được resolve.
  • Dùng ref như một prop: Có thể dùng ref như một prop mà không cần forwardRef.
  • Prewarming các sibling của Suspense: Khi component bị tạm dừng, React sẽ ngay lập tức commit phần fallback của ranh giới Suspense gần nhất.
React DOM client
  • Prop action của <form>: Form Actions tự động quản lý form và tích hợp với useFormStatus. Tự động reset form khi thành công.
  • Hỗ trợ metadata tài liệu: Có thể render native các thẻ metadata của tài liệu từ component.
  • Hỗ trợ stylesheet: Chèn stylesheet vào <head> của client trước khi hiển thị nội dung của ranh giới Suspense.
  • Hỗ trợ script bất đồng bộ: Có thể render script bất đồng bộ ở bất kỳ đâu trong cây component.
React DOM server
  • Thêm API prerenderprerenderToNodeStream: API cho tạo site tĩnh, được thiết kế để hoạt động trong các môi trường streaming như Node.js stream và web stream.
React Server Components
  • Tính năng RSC: Directive, server component và server function đã được ổn định. Các thư viện có chứa server component giờ có thể nhắm React 19 làm peer dependency.

Sắp bị loại bỏ

  • Truy cập element.ref: Loại bỏ việc truy cập element.ref, ưu tiên element.props.ref.
  • react-test-renderer: Trong React 19, react-test-renderer sẽ ghi cảnh báo deprecation và chuyển sang concurrent rendering để dùng trên web.

Thay đổi lớn

React
  • Bắt buộc dùng JSX transform mới: Cần JSX transform mới để cải thiện kích thước bundle và cho phép dùng JSX mà không cần import React.
  • Lỗi render không bị throw lại: Nếu lỗi không bị Error Boundary bắt, nó sẽ được báo qua window.reportError.
  • Loại bỏ propTypes: Việc dùng propTypes sẽ bị bỏ qua một cách im lặng. Khuyến nghị chuyển sang TypeScript.
  • Loại bỏ defaultProps của function: Có thể dùng tham số mặc định của ES6 thay thế.
  • Loại bỏ string refs: Cần migrate việc dùng string refs sang ref callback.
React DOM
  • Loại bỏ react-dom/test-utils: act được chuyển từ react-dom/test-utils sang react. Các utility khác bị loại bỏ.
  • Loại bỏ ReactDOM.render, ReactDOM.hydrate: Được thay thế bằng ReactDOM.createRootReactDOM.hydrateRoot cho concurrent rendering.

Những thay đổi đáng chú ý

React
  • Dùng <Context> làm provider: Có thể render <Context> làm provider thay cho <Context.Provider>.
  • Hỗ trợ custom element: React 19 vượt qua tất cả các bài kiểm tra custom element.
  • Thay đổi trong StrictMode: useMemouseCallback sẽ tái sử dụng kết quả memoization của lần render đầu tiên.
React DOM
  • Diff cho lỗi hydration: Khi xảy ra mismatch, React 19 sẽ ghi một lỗi duy nhất bao gồm phần khác biệt của nội dung không khớp.

Thay đổi về TypeScript

  • Cấm implicit return: ref giờ chỉ chấp nhận cleanup function. Implicit return sẽ gây lỗi.
  • useRef cần đối số khởi tạo: Đối số khởi tạo giờ là bắt buộc.
  • Typing ReactElement nghiêm ngặt hơn: props của React element giờ mặc định là unknown thay vì any.

1 bình luận

 
GN⁺ 2024-12-06
Ý kiến trên Hacker News
  • Tôi không hiểu lắm vì sao ở đây có nhiều người ghét React đến vậy
    Tôi bắt đầu sự nghiệp với Laravel và JS thuần, nhưng sau khi dùng React, việc xây dựng các ứng dụng có khả năng mở rộng trở nên thực tế hơn và frontend cũng thú vị hơn
    Dù chuyển công ty, React vẫn dễ bắt nhịp lại, và nhờ hỗ trợ TypeScript cùng hệ sinh thái lớn, tôi có cảm giác có thể xây dựng và mở rộng gần như mọi thứ khá dễ dàng
    Tôi cũng không hiểu vì sao các tính năng mới lại làm mọi người sợ. Vẫn có thể làm SPA hoặc theo cách cũ, giống như khi NoSQL DB, Spring Boot hay Kotlin xuất hiện: nếu không muốn dùng thì không dùng
    Tôi từng hiểu rằng Jetpack Compose và SwiftUI cũng lấy cảm hứng từ React; hình như tôi đã thấy trong tài liệu Android trước đây, nhưng giờ không tìm được nữa
    Tuy nhiên tôi vẫn chưa có vài chục năm kinh nghiệm, nên không biết ngày xưa các nhóm lớn làm những web app lớn như Airbnb bằng jQuery hay JS thuần thì vui đến mức nào. Giờ đây tôi thậm chí khó tưởng tượng sẽ giải quyết quản lý trạng thái, thao tác DOM và side effect bằng JS thuần ra sao
    Có lẽ một ngày nào đó tôi cũng sẽ phàn nàn về một framework mới và nói rằng React từng tốt biết bao

    • Tôi không hiểu rõ sự ác cảm với React, vì cảm giác nó thường đến từ những người chưa thật sự dùng nhiều
      Lập luận thường là “frontend lúc nào cũng đuổi theo thứ mới mẻ hào nhoáng, và React cũng chỉ là một trong số đó”, nhưng React đã tồn tại từ năm 2013 và khoảng từ 2015 đã khá mainstream rồi
      Họ cũng nói framework và thư viện làm tăng độ phức tạp, nhưng khi hỏi cụ thể là loại phức tạp nào thì gần như không nhận được câu trả lời. Nếu xây dựng một ứng dụng có ý nghĩa mà không dùng framework, cuối cùng bạn sẽ phát minh ra framework riêng thiếu khả năng quản lý, kiểm thử và tài liệu
      Các bước compile và bundling cũng thường bị phàn nàn, nhưng giờ đã có những framework đã được kiểm chứng như Expo, Next.js, Meteor, nên gần như không còn lý do để tự viết cấu hình webpack hay build pipeline
    • Phần lớn website ngay từ đầu không cần phải là ứng dụng. Một số thì cần, nhưng những trường hợp đó thường cũng cần làm riêng theo nhu cầu
      Xu hướng nhét web framework vào mọi nơi trong 10 năm qua đã tạo ra hàng loạt site chậm và dễ hỏng, thường được thiết kế quá mức nhưng trải nghiệm người dùng lại chẳng khá hơn nhiều so với năm 2008
      Với một số frontend developer, dù câu hỏi là gì thì câu trả lời cũng là một tổ hợp React / Node / Vite / Angular / Vue / Nuxt / Next / Bun / Deno / Svelte / SvelteKit, và nếu có thể thì nên chạy trên hàng chục swarm Docker do Kubernetes thống trị. Kiểu như: “Muốn đưa CV lên online à? Vậy trong 3 tuần tới hãy vẽ sơ đồ luồng trạng thái của app nhé”
      Có vẻ React bị chửi nhiều hơn vì những người chạy theo trào lưu framework đã chuyển sang thứ hào nhoáng tiếp theo, còn những người vốn ghét các framework kiểu này thì vẫn tiếp tục ghét, nên giờ không còn ai ở lại bảo vệ mớ hỗn độn này nữa. Tôi nghĩ các framework còn lại rồi cũng sẽ chịu số phận tương tự theo thời gian
    • Tôi cho rằng React thời còn class là một UI framework ổn, bình thường, nhàm chán nhưng hữu ích. Ngược lại, hook thì rất khó dùng
      Cách hoạt động thực tế bị che giấu khá nhiều và không trực quan, dễ mắc lỗi, và cũng dễ viết ra UI hiệu năng kém
      Bạn phải liên tục nghĩ xem thứ gì chạy bao nhiêu lần, phải đưa gì vào dependency array, phải đưa gì vào useCallbackuseEffect, nên tải nhận thức rất lớn
      Một phần cộng đồng còn khuyến nghị cả những dependency React mà dự án không cần, chỉ làm tăng overhead và độ phức tạp
      Business logic và UI logic cũng dễ bị trộn lẫn
    • jQuery sụp đổ rất nặng khi bắt đầu dùng để xây các ứng dụng lớn và phức tạp. Thật sự tôi không nghĩ những người đã trải qua giai đoạn đó lại nhớ nhung thời ấy
      Trong một thời gian, SPA có những nhược điểm so với MPA, nhưng nhờ các chuẩn web hiện đại và việc các SPA framework đưa vào server-side rendering, những vấn đề đó hiện nay gần như đã được giải quyết
    • Không phải là “khi NoSQL DB xuất hiện thì không ai phàn nàn”. Rất nhiều người trong chúng tôi đã phàn nàn khá lớn tiếng về việc MongoDB tệ đến mức nào
      https://www.youtube.com/watch?v=b2F-DItXtZs
  • Đây là một bản phát hành rất hay, nhưng cũng thấy hơi tội cho những người mới bước vào phát triển frontend lúc này
    Những mô tả kiểu “một hook mới dùng để sắp xếp Action bên trong Transition, truy cập trạng thái action và trạng thái pending; nhận một reducer có thể gọi Action cùng trạng thái khởi tạo dùng cho lần render đầu tiên; và cũng nhận một chuỗi tùy chọn để hỗ trợ progressive enhancement cho form nếu được truyền vào prop form action” nghe thì tính năng có vẻ tốt, nhưng quá dài dòng
    Nếu hôm nay bắt đầu làm website, có lẽ sẽ rất mông lung không biết nên bắt đầu từ đâu
    Dù vậy React vẫn là một framework xuất sắc và bản phát hành này cũng là một cải tiến. Phê bình này không chỉ nhắm vào React mà gần như là toàn bộ mảng phát triển frontend

    • Nếu đưa lời khuyên, tôi sẽ bắt đầu bằng việc tránh hẳn React nếu có thể
      Dùng kiểu render phía máy chủ truyền thống với thứ như HTMX sẽ tốt hơn nhiều
      Tôi đã kiếm tiền bằng phát triển frontend React trong 4 năm và làm website đầu tiên vào năm 2005; hiện đang chuyển một dự án client từ React sang HTMX và thấy tốt hơn hẳn
      Ít bug hơn, ít bẫy do dùng hook sai hơn
      Nếu cần render phía client thì tôi sẽ dùng Solid hoặc Vue, nhưng sẽ tránh React. Nếu không có lựa chọn thì chúc may mắn
    • Tôi nghĩ React là một cách tiếp cận thú vị, nhưng ngay từ đầu đã có những tín hiệu cảnh báo bị phớt lờ
      Tiền đề cơ bản như binding một chiều, DOM ảo, re-render và tính diff về căn bản không thuyết phục được tôi. Tức là dùng gấp đôi bộ nhớ trình duyệt, rồi mỗi tương tác đều re-render toàn bộ và tính diff
      Câu trả lời lúc đó là “trước tiên làm cho ổn định, rồi sau đó làm cho nhanh”, nhưng giờ thì đầy các cấu trúc kiểu hack để làm cho nhanh, mà lại chẳng nhanh cũng chẳng ổn định
      Tôi cho rằng các framework binding hai chiều thẳng thắn ít nhất đảm bảo được tốc độ, còn độ ổn định đến từ kinh nghiệm. React thì chỉ đơn giản là rối rắm. Thấy tiếc cho những kỹ sư mà lần đầu bước vào frontend là React, vì có lẽ việc xóa bỏ và học lại còn khó hơn nhiều so với học mới
      Từ góc nhìn của người đã đi qua VBScript, JS, jQuery, Mootools, Applets, ActionScript, YUI/Ext/Sencha, Backbone, Knockout, Angular 1, Angular 2, React, cho tới Vue 1, tôi muốn nói rằng hãy thử Flutter. Nó thật sự rất mới mẻ
      Chỉ có điều Dart là vấn đề. Nếu Flutter là TypeScript thì đã gần với lý tưởng hơn một chút, nhưng Dart vẫn tiếp tục duy trì tinh thần churn bất tận của frontend
    • Tôi lại cảm thấy ngược lại. Khi tôi bắt đầu dùng React, nó thay đổi vài tuần một lần, còn bây giờ tài liệu và API ổn định, nhất quán hơn nhiều
      Các tiêu chuẩn web nói chung cũng ổn định hơn bao giờ hết. Các lập trình viên trẻ không cần học hàng trăm mẹo layout chỉ để trang hiển thị đúng trên nhiều trình duyệt, và đôi khi cũng ít cần hack chỉ để khớp với một trình duyệt hơn
      Tôi hiểu cảm giác mệt mỏi vì JavaScript, nhưng tôi nghĩ hiện nay là một trong những thời điểm tốt nhất để học
    • Tôi chủ yếu làm coding cấp thấp và thường không thích các điểm giao với frontend web, nhưng vài năm trước thử cầm React cho một dự án cá nhân và đã rất ngạc nhiên
      Mọi thứ cảm giác giống phát triển đúng nghĩa thật sự, và so với tình hình trước đó thì như một luồng gió mới
    • Tôi nghĩ bắt đầu thì dễ. Chỉ cần không dùng tính năng tùy chọn đó là được
      Với 99% lập trình viên, trước khi app phát triển đến một mức nào đó thì sẽ không cần các tính năng như vậy, thậm chí có thể không bao giờ cần. React cũng không bắt buộc
  • Từng có thời tôi thích các framework phía client như React, nhưng cuối cùng nhận ra chúng đã thêm độ phức tạp vào mọi nơi có thể
    Backend, frontend, stack DevOps, đâu đâu cũng có độ phức tạp, và để đồng bộ các phần phức tạp phân tán đó sẽ còn tiếp tục phải thêm nhiều lớp hơn nữa

    • Khi vượt qua các ứng dụng nhỏ, framework frontend thực sự làm mọi thứ đơn giản hơn
      Việc UI tự động render lại khi dữ liệu hoặc model thay đổi là hướng đi đúng
      Cách làm chi tiết có thể tranh luận, nhưng mỗi khi dữ liệu thay đổi mà phải sửa UI trực tiếp theo kiểu mệnh lệnh thì rất khó trụ lâu xét về quy mô codebase hoặc đội ngũ
    • React là lý do khiến tôi rời xa frontend web
      Nó chồng thêm độ phức tạp khổng lồ để bắt trình duyệt web render các hộp theo cách mà ban đầu chúng không được thiết kế cho việc đó, và dưới danh nghĩa thay đổi mô hình lập trình, nó cũng làm mất đi đáng kể năng suất và hệ công cụ
      Có những ý tưởng và triển khai rất hay, nhưng tôi không chắc nó có đáng đến vậy không. Đôi khi tôi tự hỏi liệu đó có phải một kiểu cơ chế đảm bảo việc làm không
      Đây không chỉ là vấn đề của ReactJS, toàn bộ hệ sinh thái JavaScript đã phát điên với thư viện và công cụ, nhưng riêng React đặc biệt khó chịu khi bắt đầu, đến mức cuối cùng create react app ra đời để có thể tạo một app hello world trong thời gian hợp lý
    • Tôi nghĩ đó là vì phát triển phần mềm được đầu tư mạo hiểm là một chương trình phúc lợi dành cho những người thông minh và cũng muốn vui. Cũng ổn thôi
    • Tôi thích React, nhưng các thay đổi của React kể từ v16.8, khi hooks xuất hiện, có cảm giác như phô diễn kỹ thuật
      Tôi đã ngừng kỳ vọng mình sẽ hiểu lý do đổi API class component sang hook
    • Cũng cần nhìn lại xem có phải chính mình đã thêm độ phức tạp vào không
      Có thể chọn framework đơn giản hơn, cũng có thể tránh orchestration phía server
      Nếu không có lựa chọn, cũng có thể tự bắt đầu một dự án mà bạn tin là với stack đơn giản hơn sẽ có lợi thế về hiệu quả
  • Một trong những phần hay nhất của bản phát hành này là có thể dùng ref như prop. Giờ không cần forwardRef nữa

  • Bài viết blog dễ đọc hơn: https://react.dev/blog/2024/12/05/react-19

    • Ở đoạn const error = await updateName(newName);, tôi không hiểu vì sao updateName lại trả về lỗi
      Không thể cứ ném Error như đúng kiểu JS/TS sao?
  • Nếu trong 45 bình luận đến giờ, “redux” được nhắc tới 7 lần, thì ở đây tôi muốn nhắc đến Jotai như đại diện cho dòng Recoil. Có lẽ ngay cả với React 19, nó nhiều khả năng đã hoạt động mà không cần thay đổi riêng nào
    Khi độ phức tạp của frontend đủ lớn, các công cụ quản lý trạng thái khác thường trở thành trở ngại hơn mức cần thiết
    Nếu bạn đã bắt đầu ghét React, nhưng thật ra chỉ là mệt mỏi vì bức tường vô tận các hằng số action, việc luồn prop, cuộc chiến với provider/context lồng nhau, và việc chạy trốn sang pub-sub, thì những thứ như Jotai đáng để thử một lần

    • Nhóm tạo ra Jotai cũng tạo ra ZustandValtio
      https://github.com/pmndrs/zustand
      https://github.com/pmndrs/valtio
      Jotai khiến tôi cảm thấy có quá nhiều boilerplate thủ công, còn Valtio thì có nhiều “phép màu” proxy, nên dù cá nhân tôi thích nhưng không chắc đó có phải lựa chọn tốt cho cả đội không
      Zustand nằm ở giữa boilerplate và phép màu, nên tôi đã chọn nó cho một dự án lớn đang làm
    • Không hiểu sao quản lý trạng thái lại có nhiều thuật ngữ kỳ lạ đến vậy
      Vài năm trước, khi bắt đầu làm ứng dụng React, mọi gói quản lý trạng thái tôi thấy đều đầy những thuật ngữ như thế, và bây giờ vẫn vậy
      Cuối cùng, để thoát khỏi những thứ đó và tập trung vào công việc, tôi đã tự làm một giải pháp [1], và nó đang chạy tốt trong môi trường production. Tiếc là không có lựa chọn phổ biến nào hoạt động tương tự
      [1] https://github.com/facepunch/react-class-model
    • Nhìn vào trang tài liệu npm của Jotai (https://www.npmjs.com/package/jotai), tôi vẫn chưa thấy rõ nó giúp thoát khỏi việc dùng nhiều context provider hay Redux như thế nào
      Điểm hay của context hook là có thể composition, và khi kết hợp với các truy vấn được cache thì có thể tạo ra một pattern khá dễ bảo trì
      Tôi tò mò Jotai mang lại cải thiện thực chất nào ở đây
    • Tôi đã dùng Jotai trong một dự án khá lớn và khá thích nó
      Tôi thật sự hy vọng sẽ không bao giờ phải đụng tới redux hay sagas nữa
    • Mong mọi người thử https://starfx.bower.sh. Đây là một cách tiếp cận mới với quản lý trạng thái và, quan trọng hơn, quản lý side effect
  • Tôi không thích phần lớn các tính năng mới được đưa vào
    Actions và các hook useActionState / useOptimistic trông như một cái bẫy độ phức tạp lớn. Hook use có cái tên quá thiếu thông tin, và không xử lý promise được tạo bên trong component
    Chắc chắn là có lý do tốt nào đó, nhưng cách truyền promise qua prop rồi xử lý bằng hook use có vẻ sẽ tạo ra nhiều phức tạp hơn các workaround hiện tại
    Server Components cũng trông khá phức tạp, và may là tôi vẫn chưa phải xử lý chúng
    Việc cải thiện thông báo lỗi hydration là đáng hoan nghênh, còn các thay đổi dùng provider và dùng ref như prop là những cải tiến chất lượng tốt
    Nhìn chung, nếu để làm SPA thì tôi thích React/Preact. Dùng cùng một thư viện component giàu tính năng như MUI và một giải pháp quản lý trạng thái đơn giản như Preact Signals khiến việc làm SPA khá trực quan
    Tuy vậy, tôi lo độ phức tạp đang len lỏi vào từng chút một. Chỉ đọc phần mô tả các hook mới trong ghi chú phát hành thôi cũng đã thấy tải nhận thức lớn
    Ngược lại, React Compiler là công cụ thật sự cần thiết. Nó sẽ giúp component bớt phức tạp hơn vì lập trình viên không cần tự viết các tối ưu hóa điển hình bên trong component
    Tôi đang mong chờ bản phát hành và việc tích hợp với Vite, v.v.; theo tôi nghe được thì nó cũng dự kiến hỗ trợ Preact

  • Sẽ tốt hơn nếu API use được đổi sang một tên khác với tiền tố chung của hook
    Người mới học React hooks chắc sẽ bối rối khi thấy use có thể được gọi có điều kiện, còn hooks thông thường thì không

  • Thật sự rất mừng vì họ đã trì hoãn bản phát hành để giải quyết vấn đề Suspense song song
    Tôi chưa dùng thử, nhưng rất kỳ vọng; nhìn chung đây là một bản phát hành xuất sắc

  • Tin nóng: hỗ trợ đầy đủ custom elements. Tức là Web Components