-->
ads here

Introduction of Redux and React redux

advertise here
Xin chào các bạn, bài viết lần này của mình sẽ giới thiệu về một thư viện rất phổ biến trong các dự án sử dụng React/React-Native hiện nay. Đó là Redux.
Bố cục bài viết gồm 3 mục như sau:
  1. Giới thiệu chung
  2. Core concepts và 3 nguyên tắc của Redux
  3. Các thành phần chính trong Redux
Ok, chúng ta bắt đầu!
enter image description here

1. Giới thiệu chung

Redux là gì?

Theo trích dẫn từ trang chủ của Redux:
Redux is a predictable state container for JavaScript apps.
It helps you write applications that behave consistently, run in different environments (client, server, and native), and are easy to test.
Nói đơn giản, Redux là một thư viện giúp chúng ta quản lý state của 1 ứng dụng Javacript. Với redux, toàn bộ state của ứng dụng sẽ được để tại một chỗ gọi là store, và mỗi component của ứng dụng có thể truy cập bất kì state nào của ứng dụng từ store này.
Redux rất nhẹ (2KB) đã bao gồm các dependency, vì vậy chúng ta có thể thoải mái thêm vào project của mình mà không phải lo lắng việc project phình to ra.
Redux phần lớn được sử dụng với React, tuy nhiên chúng ta cũng có thể dùng với các thư viện JavaScript khác, và Flutter cũng có thể sử dụng redux.
Phần giới thiệu chung đã xong, tiếp theo chúng ta sẽ đi sâu vào các khái niệm của Redux.

2. Core concepts và 3 nguyên tắc của Redux

Core concepts:

  • Trong redux, toàn bộ state của ứng dụng của bạn được mô tả dưới dạng 1 JavaScript plain object. Object này tương tự như 1 “model” nhưng không có hàm setter, tức nghĩa chúng ta không thể tuỳ tiện access vào state và thay đổi nó vì điều này sẽ gây ra nhứng bug mà không thể tái hiện được (hard-to-reproduce bug).
  • Để muốn thay đổi state của ứng dụng, chúng ta (như đã nói ở trên: không thể trực tiếp access vào state và cập nhật giá trị mới) buộc phải dispatch một action. Action cũng tương tự state, nó là 1 plain object mô tả “what happened”. Việc đảm bảo rằng bất kì một thay đổi nào của state để được mô tả bởi action, sẽ giúp chúng ta hiểu rõ hơn thêm về những gì đang thực sự diễn ra trong ứng dụng. Nếu có bất kì thay đổi nào diễn ra, chúng ta sẽ đều biết vì sao nó thay đổi thông qua action.
  • Và cuối cùng để gắn state và action lại với nhau, ta sử dụng một function gọi là reducer, function này nhận state và action là tham số và kết quả trả về của nó là state mới sau khi action được thực hiện.
Tóm lại, một số khái niệm chính của Redux như sau:
  • Redux tuân theo nguyên tắc one-way data flow của React
  • Redux giữ state của ứng dụng bên trong 1 read-only Javascript Plain Object
  • Để thay đổi state, ta phải dispatch những action và reducer có trách nhiệm thực hiện thay đổi state.
  • Không được phép cập nhật trực tiếp vào state và thay đổi.

Three principles

Redux được xây dựng dựa trên 3 nguyên tắc sau đây:
  1. Single source of truth

Toàn bộ state của ứng dụng được lưu trong 1 object-tree bên trong 1 store duy nhất
Việc dùng chỉ duy nhất 1 state tree ngoài việc giúp dễ debug, còn cho phép state của ứng dụng được toàn vẹn trong khi phát triển. Bằng việc sử dụng duy nhất 1 state tree sẽ giúp dễ dàng thực hiện các tính năng khó hiện thực theo kiểu truyền thống như Undo/Redo.
  1. State is read-only

State là read-only, cách duy nhất để thay đổi được state là phải tạo ra 1 action (một object mô tả what happened). Điều này đảm bảo 1 việc rằng cả các view và các network callback đều không thể trực tiếp thay đổi state mà chỉ tạo ra mục đích muốn thay đổi state, từ đó gọi các action tương ứng để thay đổi.
  1. Changes are made with pure functions

Để chỉ định cách mà state sẽ thay đổi như thế nào, chúng ta sẽ dùng những hàm reducer. Reducer là nh ững pure function nhận 2 tham số là state cũ và action, và trả về giá trị là state mới sau khi thực hiện action đó. Vì reducer là những pure function nên nó sẽ tạo ra state mới chứ không thay đổi state cũ.

3. Các thành phần chính trong Redux

Để hiểu rõ hơn về các thành phần trong Redux, mình sẽ sử dụng Todo App đơn giản làm ví dụ

Action và Action creator

Actions là những payload of information sẽ gửi data từ ứng dụng đến store của redux


{
 type: "ADD_TODO",
 text: "this is new to do"
}
Như đã đề cập ở trên, action là những plain object. Action phải có trường type để chỉ ra loại action nào đang được thực hiện. Ngoài ra, action có thể chứa thêm data để cập nhật state.
Action creator đơn giản là 1 function trả về action


function addTodo(todo) {
 return {
  type: "ADD_TODO",
  text: todo
 }
}

Chúng ta có thể gửi action đến store bằng hàm store.dispatch()


store.dispatch(addTodo(todo))
// OR
store.dispatch({type: "ADD_TODO", text: "this is todo"})

Reducer

Reducer định nghĩa cách mà state của ứng dụng thay đổi bằng việc phản hồi lại những action được gửi đến store. Về cơ bản, reducer là một function nhận 2 tham số là state hiện tại và action, và kết quả trả về là state mới sau khi thực hiện action đó


   (prevState, action) => nextState
Tiếp tục ví dụ trên, ta sẽ có 1 reducer về việc thêm 1 todo mới.


const initialState = {
 todos:[]
}

const reducer = (state = initialState.todos, action) => {
 switch(action.type) {
  case: 'ADD_TODO':
   return [...state,action.text]
  default:
   return state;
 }
}
Trong một ứng dụng có thể có nhiều hơn 1 reducer, vì vậy chúng ta có thể viết tách các reducer ra riêng và sau đó dùng hàm combineReducers để nối các reducer lại thành reducer chung của cả ứng dụng


import {combineReducer} from 'redux;

const rootReducer = combineReducers({reducer1, reducer2});

Store

Nếu action mô tả what happen, reducer thể hiện how state update thì Store có nhiệm vụ nối kết 2 cái trên lại với nhau.
Store có nhiệm vụ sau đây:
  • Giữ state của ứng dụng
  • Cho phép đọc state thông qua hàm getState();
  • Cho phép state được cập nhật thông qua hàm dispatch(action);
  • Đăng ký và huỷ đăng ký cho các listener thông qua hàm subscribe;
Một điều lưu ý: mỗi ứng dụng chỉ có 1 store duy nhất, nếu bạn muốn breakdown data logic để dễ xử lý thì bạn có thể chia nhỏ các reducer ra thay vì sử dụng nhiều store.


import {combineReducer, createStore} from 'redux;

const rootReducer = combineReducers({reducer1, reducer2});

const store = createStore(rootReducer);

Kết:

Hi vọng qua bài viết này sẽ giúp các bạn có thể hiểu thêm về một thư viện để quản lý state của ứng dụng React và có thêm 1 công cụ để các bạn có thể cân nhắc áp dụng vào các dự án của mình.
Nếu thấy bài viết hay và có ích, hãy chia sẻ cho mọi người cùng biết nhé. Thanks

Reference

Advertisement
COMMENTS ()