Giới thiệu về Redux Saga
Redux Saga là một thư viện kiểm soát luồng tác vụ bất đồng bộ (asynchronous side-effect) trong ứng dụng Redux. Nó sử dụng khái niệm Generator Function trong ES6 để xử lý các tác vụ bất đồng bộ như gọi API, thực hiện các phép tính phức tạp, hoặc thậm chí là nhận dữ liệu từ thiết bị phần cứng. Điều này giúp tách biệt xử lý logic nghiệp vụ khỏi logic Redux, làm cho mã của bạn dễ quản lý và bảo trì hơn.
Các khái niệm cơ bản
Trước khi đi sâu vào Redux Saga, hãy tìm hiểu một số khái niệm cơ bản:
- Generator Function: Một Generator Function là một loại hàm đặc biệt trong JavaScript, nó có thể tạm dừng và tiếp tục lại sau đó, giữ nguyên giá trị của các biến trạng thái trong lượt thực thi trước đó.
- Effect: Trong Redux Saga, một Effect là một đối tượng Javascript đơn giản mô tả một tác vụ bất đồng bộ, chẳng hạn như gọi API, thực hiện một phép tính hoặc bất kỳ tác vụ nào có thể gây ra tác dụng phụ (side effect).
- Saga: Một Saga là một Generator Function đặc biệt trong Redux Saga, được sử dụng để xử lý các tác vụ bất đồng bộ và tạo ra các Effect.
Cài đặt Redux Saga
Để bắt đầu với Redux Saga, bạn cần cài đặt các thư viện cần thiết trong ứng dụng React của mình. Đầu tiên, hãy tạo một dự án mới bằng React và cài đặt Redux:
npx create-react-app redux-saga-tutorial cd redux-saga-tutorial npm install redux react-redux
Tiếp theo, cài đặt Redux Saga:
npm install redux-saga
Thiết lập Redux
Sau khi cài đặt xong, hãy thiết lập Redux trong ứng dụng của bạn. Tạo một tệp mới có tên store.js
trong thư mục src
và thêm nội dung sau:
import { createStore, applyMiddleware } from 'redux'; import createSagaMiddleware from 'redux-saga'; import rootReducer from './reducers'; // Tạo middleware cho Redux Saga const sagaMiddleware = createSagaMiddleware(); // Tạo store Redux const store = createStore( rootReducer, applyMiddleware(sagaMiddleware) ); export default store;
Trong đoạn mã trên, chúng ta đã tạo ra một cửa hàng Redux và áp dụng middleware cho Redux Saga. Tiếp theo, hãy tạo một reducer đơn giản trong tệp mới có tên reducers.js
:
const initialState = { data: [], loading: false, error: null }; const rootReducer = (state = initialState, action) => { switch (action.type) { default: return state; } }; export default rootReducer;
Cuối cùng, trong tệp index.js
, hãy bọc ứng dụng của bạn với Provider
từ React Redux và truyền cửa hàng Redux vào:
import React from 'react'; import ReactDOM from 'react-dom'; import App from './App'; import { Provider } from 'react-redux'; import store from './store'; ReactDOM.render( <Provider store={store}> <App /> </Provider>, document.getElementById('root') );
Bây giờ, bạn đã sẵn sàng để bắt đầu với Redux Saga!
Tạo Saga đầu tiên
Để bắt đầu với Redux Saga, hãy tạo một tệp mới có tên sagas.js
trong thư mục src
. Trong tệp này, chúng ta sẽ định nghĩa Saga đầu tiên của mình.
Tạo một Saga đơn giản
import { call, put, takeEvery } from 'redux-saga/effects'; function* fetchData() { try { const response = yield call(fetchDataFromAPI); yield put({ type: 'FETCH_DATA_SUCCESS', payload: response }); } catch (error) { yield put({ type: 'FETCH_DATA_FAILURE', error }); } } function* watchFetchData() { yield takeEvery('FETCH_DATA_REQUESTED', fetchData); } export default watchFetchData;
Trong đoạn mã trên, chúng ta đã tạo ra hai Saga:
fetchData
: Đây là Saga chính, nó thực hiện cuộc gọi API và xử lý kết quả trả về. Nó sử dụngcall
để gọi hàmfetchDataFromAPI
(chưa được định nghĩa) và sau đó sử dụngput
để gửi các hành độngFETCH_DATA_SUCCESS
hoặcFETCH_DATA_FAILURE
dựa trên kết quả trả về.watchFetchData
: Đây là một Saga theo dõi, nó sử dụngtakeEvery
để lắng nghe hành độngFETCH_DATA_REQUESTED
và gọi SagafetchData
mỗi khi hành động này được gửi đi.
Kết nối Saga với Redux Store
Sau khi định nghĩa Saga, chúng ta cần kết nối nó với cửa hàng Redux để bắt đầu theo dõi các hành động. Mở tệp store.js
và thêm đoạn mã sau:
import { createStore, applyMiddleware } from 'redux'; import createSagaMiddleware from 'redux-saga'; import rootReducer from './reducers'; import watchFetchData from './sagas'; // Tạo middleware cho Redux Saga const sagaMiddleware = createSagaMiddleware(); // Tạo store Redux const store = createStore( rootReducer, applyMiddleware(sagaMiddleware) ); // Chạy Saga sagaMiddleware.run(watchFetchData); export default store;
Trong đoạn mã mới này, chúng ta đã nhập Saga watchFetchData
và gọi phương thức run
trên đối tượng sagaMiddleware
để khởi động Saga.
Sử dụng Redux Saga trong ứng dụng
Bây giờ, hãy sửa đổi ứng dụng của bạn để sử dụng Redux Saga. Mở tệp App.js
và thêm nội dung sau:
import React, { useEffect } from 'react'; import { useDispatch, useSelector } from 'react-redux'; function App() { const dispatch = useDispatch(); const { data, loading, error } = useSelector(state => state); useEffect(() => { dispatch({ type: 'FETCH_DATA_REQUESTED' }); }, [dispatch]); return ( <div> <h1>Redux Saga Tutorial</h1> {loading && <p>Loading...</p>} {error && <p>Error: {error}</p>} <ul> {data.map(item => ( <li key={item.id}>{item.name}</li> ))} </ul> </div> ); } export default App;
Trong đoạn mã này, chúng ta đã sử dụng hook useDispatch
để lấy hàm dispatch từ Redux và useSelector
để lấy trạng thái từ cửa hàng. Trong effect useEffect
, chúng ta gửi đi hành động FETCH_DATA_REQUESTED
để bắt đầu quá trình lấy dữ liệu. Trong phần hiển thị, chúng ta hiển thị dữ liệu, thông báo đang tải hoặc thông báo lỗi tùy thuộc vào trạng thái hiện tại.
Tuy nhiên, vì chúng ta chưa có hàm fetchDataFromAPI
, nên hãy thêm một hàm giả mạo để mô phỏng việc lấy dữ liệu từ máy chủ:
const fetchDataFromAPI = () => new Promise(resolve => setTimeout(() => resolve([ { id: 1, name: 'Item 1' }, { id: 2, name: 'Item 2' }, { id: 3, name: 'Item 3' } ]), 2000 ) );
Hàm này sẽ trả về một Promise mô phỏng việc lấy dữ liệu từ máy chủ sau 2 giây.
Kết luận
Trong hướng dẫn này, chúng ta đã tìm hiểu về Redux Saga, cách cài đặt và sử dụng nó trong ứng dụng React của bạn. Chúng ta đã xây dựng một Saga đơn giản để lấy dữ liệu từ máy chủ và hiển thị nó trên giao diện người dùng. Redux Saga là một công cụ mạnh mẽ để quản lý các tác vụ bất đồng bộ trong ứng dụng Redux và giúp bạn tạo ra mã dễ đọc, dễ bảo trì hơn.
Tuy nhiên, đây chỉ là bước đầu tiên trong việc học Redux Saga. Còn rất nhiều tính năng và cách sử dụng khác của Redux Saga mà bạn cần tìm hiểu để trở thành một chuyên gia trong lĩnh vực này. Hãy tiếp tục tìm hiểu và thực hành để nâng cao kỹ năng của bạn!
Tài liệu tham khảo
Các bạn có thể tham khảo thêm nguồn khác:
Beginner Tutorial | Redux-Saga - js
$ cd redux-saga-beginner-tutorial $ npm install To start the application, run: $ npm start We are starting with the most basic use case: 2 buttons to Increment and Decrement a counter. Later, we will>
https://redux-saga.js.org/docs/introduction/BeginnerTutorial
Redux-Saga tutorial for beginners and dog lovers | HackerNoon
redux-saga is a library that aims to make application side effects (i.e. asynchronous things like data fetching and impure things like accessing the browser cache) easier to manage, more efficient to>
https://hackernoon.com/redux-saga-tutorial-for-beginners-and-dog-lovers-aa69a17db645
Redux-Saga tutorial for beginners and dog lovers - Medium
Redux-Saga tutorial for beginners and dog lovers | by Ryan J. Yost | HackerNoon.com | Medium 500 Apologies, but something went wrong on our end. Refresh the page, check Medium 's site status, or...>
https://medium.com/hackernoon/redux-saga-tutorial-for-beginners-and-dog-lovers-aa69a17db645
Getting Started | Redux-Saga - js
Getting Started | Redux-Saga Getting started Install $ npm install redux-saga or $ yarn add redux-saga Alternatively, you may use the provided UMD builds directly in the