Hiểu các thành phần của Redux và cách cài đặt Redux vào ứng dụng React

Hiểu các thành phần của Redux và cách cài đặt Redux vào ứng dụng React

Ly Nhan

3 years 5 min read

Redux là gì ?

Redux là một thư viện quản lý dữ liệu tập trung của JavaScript. Redux thường được sử dụng trong ứng dụng React để quản lý global state, dễ dàng trong việc thiết kế một kiến trúc ứng dụng tốt.

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. (redux.org)

Redux chỉ sử dụng cho React ?

Câu trả lời là không ! Redux thường được sử dụng trong React vì React chỉ là một thư viện để xây dựng giao diện người dùng, mặc dù bản thân React cũng có cơ chế quản lí state nhưng data trong React là 1 chiều, data được truyền dưới dạng props cho component con và component con bắt buộc phải nằm trong component cha.

Việc này rất khó cho việc thiết kế một ứng dụng React tốt về performance, kiến trúc. Khó scale và làm việc trong team có nhiều người. Một phần là vì những framework như Angular, Vuejs đã có sẵn cơ chế quản lý state được dựng sẵn rồi nên không sử dụng nhiều tới redux.

Tôi không muốn sử dụng Redux

Thì cũng chẳng sao cả, có rất nhiều sự lựa chọn ở bên ngoài cho bạn, như mobx, reactn, satcheljs. Hay là tự cài đặt cơ chế quản lý state cho ứng dụng của bạn bằng React Context API hoặc sử dụng kiến trúc Flux (redux build trên kiến trúc Flux) để tự build một state management cho chính ứng dụng của bạn.

Nếu các bạn chưa hiểu sao mình cần phải dùng Redux, thì mình khuyên các bạn hãy cứ sử dụng State để quản lý data và truyền data xuống cho component dưới dạng props, bạn sẽ thấm thía được nỗi đau.

Hoặc các bạn cam chịu và phát triển ứng dụng cho tới khi release, hãy dành một khoảng thời gian, mở ứng dụng React của bạn lên và review về structure, xem bạn có thể scale tiếp được với kiến trúc hiện tại không. Nếu tìm được câu trả lời rồi, thì đừng ngần ngại gì mà không setup redux cho ứng dụng của bạn, refactor hệ thống thôi.

Bạn sẽ có động lực tìm hiểu redux chỉ khi bạn đã thấm thía nỗi đau trong quá trình phát triển ứng dụng React mà không có Redux mang lại - From Tiny xàm xí :))

Tìm hiểu sơ qua về Redux

Trong React component chỉ re-render lại một khi state hoặc props của component thay đổi. Redux tạo ra một global state, mà state này lại không nằm trong component của ứng dụng, vậy làm cách nào mà những component trong React có thể nhận được data từ state của redux và re-render khi state/props thay đổi.

Như mình đã nói ở trên, redux là một thư viện quản lý dữ liệu tập trung cho javascript, React chỉ là một trong những ứng dụng của Redux, và để Redux và React có thể tương tác được với nhau, chúng ta cần phải sử dụng đến một thư viện nữa là React-redux.

Tìm hiểu sơ qua về Redux

Trong React component chỉ re-render lại một khi state hoặc props của component thay đổi. Redux tạo ra một global state, mà state này lại không nằm trong component của ứng dụng, vậy làm cách nào mà những component trong React có thể nhận được data từ state của redux và re-render khi state/props thay đổi.

Như mình đã nói ở trên, redux là một thư viện quản lý dữ liệu tập trung cho javascript, React chỉ là một trong những ứng dụng của Redux, và để Redux và React có thể tương tác được với nhau, chúng ta cần phải sử dụng đến một thư viện nữa là React-redux.

Data từ redux truyền được inject vào component dưới dạng props, khi data từ redux thay đổi thì component sẽ được trigger để re-render lại.

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

store nơi chứa global state và các phương thức:

  • getState() : return về global state

  • dispatch(actions): bắn 1 event về store để thay đổi dữ liệu

reducers nếu xem state của redux là một cây dữ liệu, thì reducer ở đây là các nhánh. Một cây dữ liệu state chứa nhiều nhánh reducer, và khi ta bắn một action về store, reducer sẽ đóng vai trò listener để lắng nghe event này có phải dành cho nhánh mình không, nếu có thì sẽ xử lý event (action).

action là một plain object (bạn có thể hiểu nó như là message) được gửi (dispatch) đến store, cấu trúc của một object action có 2 property chính là ({type: 'message id', payload: data})

workflow như sau :

  • Read : đọc dữ liệu từ redux thông qua hàm connect. Component sẽ nhận data dưới dạng props. Khi state nhận vào thay đổi thì sẽ Component sẽ re-render.

  • Write: update lại dữ liệu của redux thông qua những actions, những actions này sẽ được gửi đi thông qua hàm dispatch được cung cấp bởi store

Nghe có vẻ rối rắm đó, bạn chỉ cần nắm ý tưởng vậy thôi, dưới đây mình sẽ hướng dẫn chi tiết. LET'S GO !

Cài đặt Redux

Install Redux:

npm install redux react-redux --save

Khởi tạo store:

import {createStore} from 'redux';
export const store = createStore(
  reducers,// tham số đầu tiên là cac reducers.
  defaultReducers, // tham số thứ 2 là reducer mặc định 
  middleware, // tham số thứ 3 là danh sách các middlewares
);

Khởi taọ reducers. Reducer là một pure function có 2 tham số, tham số đầu tiên là giá trị mặc định của reducer, giá trị thứ 2 chính là action được gửi đi từ hàm dispatch. Reducer có thể lắng nghe tất cả các action được gửi đi từ hàm dispatch.

Như đã nói reducers là những nhánh data của global state, thực tế trong một ứng dụng thường có rất nhiều reducers, sử dụng hàm combineReducers để combine tất cả reducers lại.

import {createStore, combineReducers } from 'redux';
const defaultState="this is default Message! dispatch an action to change me"
const reducers = combineReducers({
  message: (state=defaultState, action) => {
    return state;
  },
});
export const store = createStore(reducers, {});

Vậy là chúng ta đã tạo được một store đơn giản cho ứng dụng React. Giờ đến giai đoạn tích hợp nó vào React thôi.

Sử dụng React-redux để kết nối React với Redux

Để hiểu chỗ này kĩ hơn, các bạn nên tìm hiểu React Context trước khi đến bước intergrate này nhé.

React-redux sử dụng React Context API, toàn bộ ứng dụng của bạn phải được render ở trong component <Provider store={store}> . Component Provider như là một cái adapter nhận vào object store chúng ta vừa tạo ở trên, sau đó truyền những function/state của store này dưới dạng props xuống component của React thông qua hàm connect.

import {store} from './redux/store';
import {Provider} from 'react-redux';
const ClientApp = () => (
  <Provider store={store}>
    <App />
  </Provider>
);
ReactDOM.render(<ClientApp />, document.getElementById('root'));

Yup! Easy. Bây giờ mình connect component <App /> để lấy state và function dispatch để read/write từ store.

import {connect} from "react-redux"
export default connect(
  state => {
    console.log('state', state);
    return {message:state.message};
  },
  (dispatch, props) => {
    return {dispatch};
  },
)(App);

Yesssssss, như vậy là mình đã connect thành công component App để lấy data cần thiết để render component, và hàm dispatch để gửi những actions đến store để thay đổi data của store.

Dispatch một action

Bây giờ mình sẽ thử dispatch đi một action đơn giản xem store có nhận được không.

function App(props) {
  const {message, dispatch} = props;
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        {message}
        <button
          onClick={() => {
            dispatch({
              type: 'CHANGE_MESSAGE',
              payload: 'this is new message',
            });
          }}>
          Change Message
        </button>
      </header>
    </div>
  );
}

Khi message được gửi đi, reducer sẽ đóng vai trò là listener lắng nghe những actions này, giả sử một reducers nào có nhiệm vụ lắng nghe action này để handle, thì trong reducer cần phải khai báo một handler cho action này.

Đây chỉ là concept đơn giản nhất khi tích hợp Redux vào Reat. Các bạn cần nắm được Redux work với một ứng dụng React như thế nào trước khi thiết kế ở tầm lớn hơn.

High level experience in web design and development knowledge, producing quality work.

© Nextlint_2023 All Rights Reserved

Privacy Policy Terms of Use