Redux khá là phổ biến trong thư viện JavaScript. Tuy nhiên, không phải tất cả chúng ta đều biết nó là gì và cách sử dụng nó ra sao. Trong bài viết này, chúng ta sẽ xem tại sao nên sử dụng redux bằng cách phân tích những lợi ích mà nó mang lại và cách hoạt động của nó.

1. Redux là gì?

Redux là một thư viện quản lý trạng thái (state management) cho ứng dụng web, phổ biến trong các ứng dụng phát triển dựa trên JavaScript và React. Nó giúp quản lý trạng thái của ứng dụng một cách dễ dàng và hiệu quả, đồng thời giúp tạo ra một luồng dữ liệu (data flow) đơn giản và dễ theo dõi.

Redux giúp quản lý trạng thái phức tạp trong ứng dụng web bằng cách tách biệt logic và giao diện người dùng. Nó cung cấp một cách tiếp cận dễ dàng và dễ theo dõi để theo dõi và cập nhật trạng thái, đồng thời giúp đảm bảo tính nhất quán của dữ liệu trong ứng dụng.

2. Lịch sử ra đời của Redux

Redux được tạo ra bởi Dan Abramov và Andrew Clark. Nó xuất hiện đầu tiên vào năm 2015 và được giới thiệu trong một bài viết trên blog của Dan Abramov, với tên gọi "Redux: Được tạo ra để giải quyết vấn đề của Flux".

Redux được xây dựng dựa trên các ý tưởng của kiến trúc Flux, một mô hình quản lý trạng thái phát triển bởi Facebook. Tuy nhiên, Redux đã đơn giản hóa và cải thiện kiến trúc Flux bằng cách sử dụng các khái niệm như nguồn dữ liệu đơn duy nhất (single source of truth) và hàm reducer.

Sau khi được giới thiệu, Redux nhanh chóng trở thành một trong những thư viện phổ biến và mạnh mẽ nhất để quản lý trạng thái trong các ứng dụng web sử dụng React. Sự đơn giản và tính nhất quán của Redux đã thu hút sự quan tâm và sự ưa chuộng từ cộng đồng phát triển phần mềm.

Redux không chỉ hữu ích trong các ứng dụng React, mà còn có thể được sử dụng trong các ứng dụng web sử dụng các framework khác như Angular hoặc Vue.js.

Kể từ khi ra mắt, Redux đã trở thành một công cụ phổ biến và quan trọng trong việc quản lý trạng thái ứng dụng web phức tạp, và cộng đồng phát triển tiếp tục đóng góp và phát triển Redux để đáp ứng các yêu cầu và nhu cầu mới trong lĩnh vực này.

3. Nguyên lý hoạt động của Redux

Nguyên lý hoạt động của Redux dựa trên một số khái niệm và quy trình cơ bản sau:

Single source of truth (Nguồn dữ liệu đơn duy nhất): Tất cả trạng thái của ứng dụng được lưu trữ trong một đối tượng gọi là "store". Store là một cây trạng thái (state tree) không thể thay đổi trực tiếp.

State is read-only (Trạng thái chỉ đọc): Trạng thái không được thay đổi trực tiếp. Để thay đổi trạng thái, ta cần tạo ra một hành động (action) mô tả sự thay đổi.

Changes are made with pure functions (Thay đổi được thực hiện bằng các hàm thuần túy): Reducer là các hàm thuần túy nhận vào trạng thái hiện tại và hành động, và trả về một trạng thái mới. Việc thay đổi trạng thái xảy ra thông qua việc gọi các reducer.

Unidirectional data flow (Luồng dữ liệu một chiều): Khi một hành động được gửi đến store, nó sẽ được chuyển đến reducer để xử lý và tạo ra trạng thái mới. Sau đó, trạng thái mới được cập nhật trong store và thông báo cho các thành phần ứng dụng khác về sự thay đổi.

Time-travel debugging (Gỡ lỗi theo thời gian): Redux hỗ trợ tính năng gỡ lỗi theo thời gian, cho phép bạn xem lại các hành động đã xảy ra và trạng thái tại mỗi thời điểm trong quá trình phát triển.

Quy trình cơ bản khi sử dụng Redux bao gồm:

Định nghĩa trạng thái ban đầu: Xác định trạng thái ban đầu của ứng dụng và khởi tạo store.

Định nghĩa các hành động (actions): Xác định các hành động mà ứng dụng có thể thực hiện, mô tả các sự kiện và dữ liệu đi kèm.

Ví dụ về trình tạo Actions:

``` const setLoginStatus = ( name,

password ) => {

return {

type : “LOGIN” ,

payload : {

username : “foo” ,

password : “bar” }

}

}


<p><strong>Viết reducer:</strong> X&aacute;c định c&aacute;c reducer, l&agrave; c&aacute;c h&agrave;m nhận v&agrave;o trạng th&aacute;i hiện tại v&agrave; một h&agrave;nh động, v&agrave; trả về một trạng th&aacute;i mới dựa tr&ecirc;n h&agrave;nh động.</p>

<p>Một v&iacute; dụ đơn giản về c&aacute;ch thức hoạt động của Reducers trong Redux:</p>

const LoginComponent = ( state = initialState , action ) => { switch ( action . type ) {

// Bộ Reducers này xử lý bất cứ hành động nào với kiểu “LOGIN”. Trường hợp “LOGIN” : trả về trạng thái . map ( user => { if (user . username ! == action . username ) { return user ; }

if ( user . password == action . password ) { return { … user , login_status : “LOGGED IN” } } } ); default : trả về trạng thái ; } } ;


<p><strong>Tạo store:</strong> Tạo store bằng c&aacute;ch kết hợp reducer v&agrave; trạng th&aacute;i ban đầu.</p>

<p><strong>Gửi h&agrave;nh động (dispatch actions):</strong> Sử dụng h&agrave;m dispatch để gửi h&agrave;nh động tới store. Store sẽ gọi c&aacute;c reducer v&agrave; cập nhật trạng th&aacute;i.</p>

<p><strong>Cập nhật giao diện người d&ugrave;ng:</strong> C&aacute;c th&agrave;nh phần React hoặc c&aacute;c th&agrave;nh phần kh&aacute;c sẽ được th&ocirc;ng b&aacute;o về sự thay đổi trạng th&aacute;i v&agrave; cập nhật giao diện dựa tr&ecirc;n trạng th&aacute;i mới.</p>

<p>Qua việc thực hiện c&aacute;c h&agrave;nh động v&agrave; cập nhật trạng th&aacute;i theo c&aacute;ch n&agrave;y, Redux gi&uacute;p đảm bảo t&iacute;nh nhất qu&aacute;n v&agrave; dễ theo d&otilde;i trong việc quản l&yacute; trạng th&aacute;i của ứng dụng.</p>

<h2>4. Cấu tr&uacute;c của Redux</h2>

<p>Cấu tr&uacute;c đầy đủ của Redux bao gồm c&aacute;c th&agrave;nh phần ch&iacute;nh sau:</p>

<p><img alt="" src="https://asia-1-fileserver-2.stringee.com/0/asia-1_1_UGPINMF6YU9SCIX/1688204073-cau-truc-cua-redux.png" style="height:400px; width:747px" /></p>

<h3>4.1 Actions (H&agrave;nh động):</h3>

<p>Actions l&agrave; c&aacute;c đối tượng JavaScript chứa th&ocirc;ng tin về sự kiện xảy ra trong ứng dụng. Mỗi action c&oacute; một thuộc t&iacute;nh bắt buộc l&agrave; &quot;type&quot; để x&aacute;c định loại h&agrave;nh động. Actions c&oacute; thể c&oacute; th&ecirc;m c&aacute;c thuộc t&iacute;nh kh&aacute;c để mang th&ocirc;ng tin đi k&egrave;m.</p>

<h3>4.2 Reducers (Bộ giảm thiểu):&nbsp;</h3>

<p>Reducers l&agrave; c&aacute;c h&agrave;m xử l&yacute; để x&aacute;c định c&aacute;ch thay đổi trạng th&aacute;i của ứng dụng dựa tr&ecirc;n c&aacute;c h&agrave;nh động. Mỗi reducer nhận v&agrave;o trạng th&aacute;i hiện tại v&agrave; một action, sau đ&oacute; trả về một trạng th&aacute;i mới. Reducers n&ecirc;n được viết dưới dạng h&agrave;m thuần t&uacute;y (pure functions) để đảm bảo t&iacute;nh dự đo&aacute;n v&agrave; kh&ocirc;ng c&oacute; t&aacute;c động phụ.</p>

<h3>4.3 Store (Ngăn chứa):&nbsp;</h3>

<p>Store l&agrave; nơi lưu trữ to&agrave;n bộ trạng th&aacute;i của ứng dụng. N&oacute; l&agrave; đối tượng ch&iacute;nh của Redux v&agrave; bao gồm c&aacute;c phương thức để truy cập v&agrave; cập nhật trạng th&aacute;i. Store cũng l&agrave; nơi kết nối giữa actions v&agrave; reducers, nhận c&aacute;c actions v&agrave; gọi reducers để cập nhật trạng th&aacute;i.</p>

<h3>4.4 Middleware (Trung gian):&nbsp;</h3>

<p>Middleware l&agrave; một lớp trung gian t&ugrave;y chọn được sử dụng để mở rộng chức năng của Redux. N&oacute; cho ph&eacute;p ch&uacute;ng ta can thiệp v&agrave;o qu&aacute; tr&igrave;nh xử l&yacute; h&agrave;nh động trước khi ch&uacute;ng được gửi đến reducers. Middleware c&oacute; thể được sử dụng để thực hiện c&aacute;c t&aacute;c vụ như ghi log, xử l&yacute; bất đồng bộ hoặc thực hiện c&aacute;c t&aacute;c vụ phức tạp kh&aacute;c.</p>

<h3>4.5 Connectors (Kết nối):&nbsp;</h3>

<p>Connectors l&agrave; một c&aacute;ch để kết nối c&aacute;c th&agrave;nh phần React v&agrave; Redux store. Ch&uacute;ng gi&uacute;p lấy trạng th&aacute;i từ store v&agrave; gửi actions đến store, từ đ&oacute; cho ph&eacute;p c&aacute;c th&agrave;nh phần React truy cập v&agrave; sử dụng dữ liệu từ store v&agrave; tương t&aacute;c với n&oacute;.</p>

<p>Cấu tr&uacute;c tr&ecirc;n gi&uacute;p Redux quản l&yacute; trạng th&aacute;i của ứng dụng một c&aacute;ch hiệu quả, đảm bảo t&iacute;nh nhất qu&aacute;n v&agrave; dễ theo d&otilde;i.</p>

<h2>5. L&yacute; do n&ecirc;n sử dụng Redux reactjs</h2>

<p>Redux mang đến những ưu điểm tuyệt vời khi sử dụng để quản l&yacute; trạng th&aacute;i của Reactjs:</p>

<p><img alt="" src="https://asia-1-fileserver-2.stringee.com/0/asia-1_1_Z2HIP93HSVOBFR9/1688204114-li-do-nen-su-dung-redux.png" style="height:463px; width:749px" /></p>

<ul>
    <li><strong>Quản l&yacute; trạng th&aacute;i phức tạp: </strong>Redux gi&uacute;p quản l&yacute; trạng th&aacute;i của ứng dụng một c&aacute;ch hiệu quả, đặc biệt l&agrave; khi ứng dụng c&oacute; trạng th&aacute;i phức tạp v&agrave; c&aacute;c th&agrave;nh phần ứng dụng cần truy cập v&agrave; chia sẻ dữ liệu trạng th&aacute;i.</li>
    <li><strong>T&iacute;nh nhất qu&aacute;n: </strong>Redux &aacute;p dụng nguy&ecirc;n tắc &quot;single source of truth&quot; v&agrave; &quot;state is read-only&quot;, gi&uacute;p đảm bảo t&iacute;nh nhất qu&aacute;n của dữ liệu trong ứng dụng. Mọi thay đổi trạng th&aacute;i đều th&ocirc;ng qua việc gửi h&agrave;nh động v&agrave; được xử l&yacute; bởi c&aacute;c reducer, từ đ&oacute; đảm bảo rằng trạng th&aacute;i được cập nhật một c&aacute;ch dễ d&agrave;ng v&agrave; dễ theo d&otilde;i.</li>
    <li><strong>Dễ d&agrave;ng theo d&otilde;i v&agrave; gỡ lỗi:</strong> Redux cung cấp t&iacute;nh năng gỡ lỗi theo thời gian (time-travel debugging) cho ph&eacute;p xem lại c&aacute;c h&agrave;nh động v&agrave; trạng th&aacute;i trước đ&oacute;, gi&uacute;p dễ d&agrave;ng x&aacute;c định v&agrave; sửa lỗi.</li>
    <li><strong>Ph&acirc;n t&aacute;ch logic v&agrave; giao diện người d&ugrave;ng:</strong> Redux gi&uacute;p t&aacute;ch biệt logic ứng dụng v&agrave; giao diện người d&ugrave;ng. Việc quản l&yacute; trạng th&aacute;i được thực hiện bởi Redux, trong khi c&aacute;c th&agrave;nh phần React chỉ cần tương t&aacute;c với Redux th&ocirc;ng qua c&aacute;c kết nối (connectors). Điều n&agrave;y gi&uacute;p tăng t&iacute;nh t&aacute;i sử dụng v&agrave; dễ bảo tr&igrave; của m&atilde; nguồn.</li>
    <li><strong>Hỗ trợ cho c&aacute;c t&iacute;nh năng mở rộng:</strong> Redux c&oacute; khả năng t&iacute;ch hợp c&aacute;c middleware để mở rộng chức năng của n&oacute;. Điều n&agrave;y cho ph&eacute;p thực hiện c&aacute;c t&aacute;c vụ như xử l&yacute; bất đồng bộ, ghi log, định dạng dữ liệu v&agrave; nhiều hơn nữa.</li>
</ul>

<p>Tuy nhi&ecirc;n, việc sử dụng Redux trong ứng dụng ReactJS cũng đ&ograve;i hỏi một số c&ocirc;ng sức v&agrave; c&uacute; ph&aacute;p bổ sung. Việc đ&aacute;nh gi&aacute; lợi &iacute;ch v&agrave; t&ugrave;y chỉnh Redux ph&ugrave; hợp với y&ecirc;u cầu cụ thể của dự &aacute;n l&agrave; điều quan trọng để đảm bảo sự hiệu quả v&agrave; tiện &iacute;ch của việc sử dụng n&oacute;.</p>

<h2>Tạm kết</h2>

<p>Việc sử dụng Redux gi&uacute;p ch&uacute;ng ta tạo ra ứng dụng c&oacute; quy m&ocirc; lớn v&agrave; phức tạp m&agrave; vẫn duy tr&igrave; được t&iacute;nh r&otilde; r&agrave;ng v&agrave; dễ bảo tr&igrave;. Với Redux, bạn sẽ c&oacute; c&ocirc;ng cụ mạnh mẽ để quản l&yacute; trạng th&aacute;i v&agrave; x&acirc;y dựng c&aacute;c ứng dụng web tốt hơn. H&atilde;y &aacute;p dụng kiến thức về Redux v&agrave; kh&aacute;m ph&aacute; sự tiến bộ v&agrave; hiệu quả trong qu&aacute; tr&igrave;nh ph&aacute;t triển phần mềm của bạn</p>

<p>Theo d&otilde;i <a href="https://stringee.com/vi/contact-sales?utm_source=Blog&amp;utm_medium=anchor_text&amp;utm_campaign=redux-la-gi" target="_blank">stringee.com</a> để cập nhật những th&ocirc;ng tin v&agrave; kiến thức mới nhất về ng&agrave;nh CNTT lập tr&igrave;nh.</p>

<p>&nbsp;</p>