Context API vs Redux: Lựa chọn nào tốt hơn?

6 min read

Khi phát triển một dự án React, để ứng dụng có thể hoạt động trơn tru nhất thì việc quản lý state rất quan trọng, state cho phép tác động đến cách mà giao diện được hiển thị và cách mà nó được thay đổi.

Ngoài những state hoạt động trong một component duy nhất, đôi khi nó sẽ cần được chia sẻ giữa các component khác nhau. Bạn có thể nghĩ đến cách tạo một state ở component lớn và truyền xuống các component nhỏ hơn, tuy nhiên, với những component quá phức tạp khi có quá nhiều level hoặc 2 component nằm cách nhau quá xa trong cây dự án thì việc truyền như thế có thể khiển dự án quá khó để bảo trì.

Do vậy, các state management được ra đời như Redux, Context API, Zustand, Recoil, …, khi này bạn chỉ cần tương tác với chúng khi cần ở bất kì đâu bằng các selector, hook, … mà không cần phải truyền xuống một cấp nào cả.

Trong số các state management kể trên, mình thấy hay được sử dụng trong các dự án là Redux và Context API, vậy trong bài viết này, chúng ta sẽ tìm hiểu xem chúng là gì và nên lựa chọn gì cho dự án React của bạn nhé.

Redux

Đây là một công cụ hữu ích giúp bạn xây dựng các ứng dụng có tính nhất quán, hoạt động linh hoạt trên nhiều môi trường (client, server và native), và dễ dàng kiểm thử. Sáng tạo từ ngôn ngữ Elm và kiến trúc Flux của Facebook, Redux thường được kết hợp sử dụng cùng với React.

Redux có nhiệm vụ quản lý trạng thái phức tạp trong ứng dụng web, giúp tách biệt logic và giao diện người dùng. Với tiếp cận dễ hiểu và theo dõi, Redux giúp bạn theo dõi và cập nhật trạng thái một cách hiệu quả, đồng thời đảm bảo tính nhất quán cho dữ liệu trong ứng dụng, từ đó dễ dàng debug khi gặp lỗi.

Redux hoạt động bằng cách tạo một store, store này chứa các state và tất cả những thành phần nằm trong sự kiểm soát của store này đều sẽ có thể dễ dàng lấy một state bất kì ra thông qua selector cũng như dễ dàng thay đổi nó thông qua hành động dispatch một action.

Các thành phần chính của Redux:

  • Action là một đối tượng sẽ được gửi đi để xác định bạn đang muốn thực hiện hành động gì. Ví dụ như nếu muốn thay đổi state count bạn có thể dispatch một đối tượng dạng như:
    { type: "UPDATE_COUNT", payload: { value: 10 } }
  • Reducer là một event handler được tạo ra để có thể xử lý các sự kiện hướng tới store
  • Store lưu trạng thái ứng dụng, bạn có thể access các state được lưu, update state, …

Lưu ý khi sử dụng Redux:

  • Giá trị lưu trong Redux về bản chất vẫn là state nên nó thừa hưởng mọi tính chất của state, chỉ khác ở chỗ nó là global state (state toàn cục) nên khi giá trị lưu trong Redux thay đổi thì tất cả component đang sử dụng giá trị đó cũng sẽ thay đổi theo.
  • Chuẩn hoá dữ liệu (Normalized State) trước khi lưu chúng vào Redux để đảm bảo hiệu suất của ứng dụng đạt ở mức cao.
  • Nên thực hiện việc xử lý logic ở các hàm bên ngoài, hạn chế xử lý logic phức tạp bên trong Redux, Redux chỉ nên sử dụng để lưu dữ liệu cuối cùng sau khi đã qua xử lý.

Các trường hợp nên sử dụng Redux

  • Quản lý các state phức tạp cần chia sẻ giữa nhiều thành phần
  • State cần chia sẻ global

Context API

Context API là một tính năng có sẵn trong React, nó trực tiếp chứa các state bên trong và có thể được sử dụng bởi các thành phần con nằm trong nó, nghe sơ qua thì cũng khá là giống với Redux.

Context được khởi tạo thông qua createContext, khi sử dụng, bạn có thể lấy các giá trị nằm trong nó thông qua useContext và xác định context muốn dùng, lưu ý là nơi dùng phải nằm trong context đó.

Các thành phần chính của Context

  • Provider: Cung cấp dữ liệu cho các thành phần con. Thành phần Provider nhận một prop là value, truyền dữ liệu này tới mọi thành phần con nằm trong Context.
  • Consumer: Là những component nằm trong Context, có thể truy cập giá trị của Context thông qua useContext

Lưu ý khi sử dụng Context:

  • Không nên lạm dụng context: Do hiệu suất của context không cao, render lại tất cả khi một state thay đổi cho nên chỉ nên sử dụng cho các module nhỏ, ít logic
  • Không nên sử dụng context để lưu những state thay đổi quá thường xuyên
  • Debugging Context: Việc gỡ lỗi của Context khá khó khăn do giá trị được chia sẻ nhiều thành phần, không hiển thị trong props

Các trường hợp sử dụng Context

  • Theming: bạn có thể sử dụng Context API để lưu trữ giá trị theme hiện tại của ứng dụng và có thể sử dụng nó ở tất cả các component mà bạn muốn.
  • User Authentication: bạn có thể sử dụng Context API để lưu trữ thông tin của user hiện tại đang login trên ứng dụng và kiểm tra quyền truy cập các trang dựa theo permission của user.
  • Multilingual: nếu trang web của bạn có hỗ trợ nhiều ngôn ngữ thì bạn cũng có thể sử dụng Context API để lưu trữ trạng thái được chọn của ngôn ngữ hiện tại.

So sánh Redux – Context API

ReduxContext API
Quản lý tập chung thông qua Action, ReducerQuản lý phi tập chung dưới dạng Provider – Consumer
Hiệu suất tốt cho các ứng dụng lớn do khi một state thay đổi chỉ ảnh hưởng đến các thành phần sử dụng chính state đóHiệu suất kém hơn cho các ứng dụng lớn do khi một state thay đổi, mọi thành phần thuộc context sẽ render lại
Phức tạp để sử dụng Thân thiện do ít cấu hình
Debug dễ với Redux Dev ToolsKhó debug hơn nếu Component Tree bị lồng quá nhiều

Tổng kết

Context API và Redux đóng vai trò là giải pháp quản lý trạng thái trong React nhưng đáp ứng các nhu cầu khác nhau. Context API là giải pháp thay thế tiện lợi cho các ứng dụng đơn giản hơn. Ngược lại, Redux phù hợp hơn với các dự án phức tạp đòi hỏi quản lý trạng thái tập trung và luồng dữ liệu có thể dự đoán được.

Khi quyết định giữa React Redux và Context, hãy cân nhắc đến quy mô và độ phức tạp của ứng dụng, kinh nghiệm của nhóm và các yêu cầu cụ thể của dự án. Hãy nhớ rằng cả hai giải pháp đều có vị trí của chúng trong hệ sinh thái React và lựa chọn tốt nhất phụ thuộc vào bối cảnh nhu cầu của ứng dụng.

Tham khảo

Avatar photo

Unity IAP: Triển khai Mua Hàng Consumable

Giới Thiệu Việc tích hợp tính năng mua hàng trong ứng dụng Unity là không thể tránh khỏi. Mua hàng trong ứng dụng có...
Avatar photo Tam Canh Le Chi
6 min read

Leave a Reply

Your email address will not be published. Required fields are marked *