Redux Saga CRUD ví dụ - Hướng dẫn chi tiết cho CRUD với Redux Saga

Redux Saga CRUD ví dụ - Hướng dẫn chi tiết cho CRUD với Redux Saga

Bài viết này sẽ giải thích chi tiết cách sử dụng Redux Saga để thực hiện các hoạt động CRUD (Tạo, Đọc, Cập nhật và Xóa) trong ứng dụng React. Ví dụ minh họa sẽ hướng dẫn bạn cách làm việc với API để thực hiện các tác vụ CRUD sử dụng Redux Saga.
02/03/2024
10,352 Lượt xem

Thiết lập dự án

Trước khi bắt đầu, hãy khởi tạo một dự án React mới bằng lệnh:

npx create-react-app redux-saga-crud-example

Sau đó, cài đặt các gói cần thiết:

npm install redux react-redux redux-saga axios

Trong đó:

  • redux và react-redux: Các gói cơ bản để sử dụng Redux trong ứng dụng React.
  • redux-saga: Thư viện chính để xử lý các tác vụ bất đồng bộ.
  • axios: Thư viện gọi API.

Cấu trúc thư mục

Sau khi thiết lập dự án, hãy tạo cấu trúc thư mục như sau:

src/
├── components/
│   └── ProductList.js
├── redux/
│   ├── actions.js
│   ├── reducers.js
│   ├── sagas.js
│   └── store.js
├── services/
│   └── api.js
├── App.js
└── index.js

Trong đó:

  • components/: chứa các component của ứng dụng.
  • redux/: chứa các tệp quan trọng liên quan đến Redux và Redux Saga.
  • services/: chứa các hàm gọi API.
  • App.js: component gốc của ứng dụng.
  • index.js: tệp khởi chạy ứng dụng.

Tạo API giả lập

Để minh họa các hoạt động CRUD, chúng ta sẽ sử dụng một API giả lập bằng JSONPlaceholder. JSONPlaceholder là một API giả lập miễn phí, được sử dụng rộng rãi để thử nghiệm các ứng dụng.

Trong services/api.js, tạo các hàm gọi API như sau:

import axios from 'axios';

const API_BASE_URL = 'https://jsonplaceholder.typicode.com';

export const getProducts = () => {
    return axios.get(`${API_BASE_URL}/posts`);
};

export const createProduct = (product) => {
    return axios.post(`${API_BASE_URL}/posts`, product);
};

export const updateProduct = (product) => {
    return axios.put(`${API_BASE_URL}/posts/${product.id}`, product);
};

export const deleteProduct = (id) => {
    return axios.delete(`${API_BASE_URL}/posts/${id}`);
};

Các hàm trên sẽ gọi đến API của JSONPlaceholder để thực hiện các hoạt động CRUD tương ứng.

Tạo Redux Saga cho hoạt động CRUD

Tiếp theo, trong tệp redux/sagas.js, chúng ta sẽ tạo các Saga cho các hoạt động CRUD:

import { call, put, takeEvery } from 'redux-saga/effects';
import {
    getProducts,
    createProduct,
    updateProduct,
    deleteProduct,
} from '../services/api';
import {
    GET_PRODUCTS_REQUEST,
    CREATE_PRODUCT_REQUEST,
    UPDATE_PRODUCT_REQUEST,
    DELETE_PRODUCT_REQUEST,
    getProductsSuccess,
    getProductsFailure,
    createProductSuccess,
    createProductFailure,
    updateProductSuccess,
    updateProductFailure,
    deleteProductSuccess,
    deleteProductFailure,
} from './actions';

function* fetchProductsSaga() {
    try {
        const response = yield call(getProducts);
        yield put(getProductsSuccess(response.data));
    } catch (error) {
        yield put(getProductsFailure(error));
    }
}

function* createProductSaga(action) {
    try {
        const response = yield call(createProduct, action.payload);
        yield put(createProductSuccess(response.data));
    } catch (error) {
        yield put(createProductFailure(error));
    }
}

function* updateProductSaga(action) {
    try {
        const response = yield call(updateProduct, action.payload);
        yield put(updateProductSuccess(response.data));
    } catch (error) {
        yield put(updateProductFailure(error));
    }
}

function* deleteProductSaga(action) {
    try {
        yield call(deleteProduct, action.payload);
        yield put(deleteProductSuccess(action.payload));
    } catch (error) {
        yield put(deleteProductFailure(error));
    }
}

function* productSaga() {
    yield takeEvery(GET_PRODUCTS_REQUEST, fetchProductsSaga);
    yield takeEvery(CREATE_PRODUCT_REQUEST, createProductSaga);
    yield takeEvery(UPDATE_PRODUCT_REQUEST, updateProductSaga);
    yield takeEvery(DELETE_PRODUCT_REQUEST, deleteProductSaga);
}

export default productSaga;

Trong đoạn mã trên, chúng ta đã tạo các Saga cho các hoạt động CRUD tương ứng. Mỗi Saga sẽ gọi đến các hàm API trong services/api.js và xử lý kết quả trả về bằng cách gọi các action tương ứng.

Cuối cùng, chúng ta tạo một Saga chính (productSaga()) để lắng nghe các action từ Redux và gọi các Saga tương ứng.

Tạo Redux Actions và Reducers

Tiếp theo, trong tệp redux/actions.js, chúng ta tạo các action cho các hoạt động CRUD:

export const GET_PRODUCTS_REQUEST = 'GET_PRODUCTS_REQUEST';
export const GET_PRODUCTS_SUCCESS = 'GET_PRODUCTS_SUCCESS';
export const GET_PRODUCTS_FAILURE = 'GET_PRODUCTS_FAILURE';

export const CREATE_PRODUCT_REQUEST = 'CREATE_PRODUCT_REQUEST';
export const CREATE_PRODUCT_SUCCESS = 'CREATE_PRODUCT_SUCCESS';
export const CREATE_PRODUCT_FAILURE = 'CREATE_PRODUCT_FAILURE';

export const UPDATE_PRODUCT_REQUEST = 'UPDATE_PRODUCT_REQUEST';
export const UPDATE_PRODUCT_SUCCESS = 'UPDATE_PRODUCT_SUCCESS';
export const UPDATE_PRODUCT_FAILURE = 'UPDATE_PRODUCT_FAILURE';

export const DELETE_PRODUCT_REQUEST = 'DELETE_PRODUCT_REQUEST';
export const DELETE_PRODUCT_SUCCESS = 'DELETE_PRODUCT_SUCCESS';
export const DELETE_PRODUCT_FAILURE = 'DELETE_PRODUCT_FAILURE';

export const getProductsRequest = () => ({
    type: GET_PRODUCTS_REQUEST,
});

export const getProductsSuccess = (products) => ({
    type: GET_PRODUCTS_SUCCESS,
    payload: products,
});

export const getProductsFailure = (error) => ({
    type: GET_PRODUCTS_FAILURE,
    payload: error,
});

export const createProductRequest = (product) => ({
    type: CREATE_PRODUCT_REQUEST,
    payload: product,
});

export const createProductSuccess = (product) => ({
    type: CREATE_PRODUCT_SUCCESS,
    payload: product,
});

export const createProductFailure = (error) => ({
    type: CREATE_PRODUCT_FAILURE,
    payload: error,
});

export const updateProductRequest = (product) => ({
    type: UPDATE_PRODUCT_REQUEST,
    payload: product,
});

export const updateProductSuccess = (product) => ({
    type: UPDATE_PRODUCT_SUCCESS,
    payload: product,
});

export const updateProductFailure = (error) => ({
    type: UPDATE_PRODUCT_FAILURE,
    payload: error,
});

export const deleteProductRequest = (id) => ({
    type: DELETE_PRODUCT_REQUEST,
    payload: id,
});

export const deleteProductSuccess = (id) => ({
    type: DELETE_PRODUCT_SUCCESS,
    payload: id,
});

export const deleteProductFailure = (error) => ({
    type: DELETE_PRODUCT_FAILURE,
    payload: error,
});

Trong tệp redux/reducers.js, chúng ta tạo reducers để xử lý các action trên:

import {
    GET_PRODUCTS_REQUEST,
    GET_PRODUCTS_SUCCESS,
    GET_PRODUCTS_FAILURE,
    CREATE_PRODUCT_SUCCESS,
    UPDATE_PRODUCT_SUCCESS,
    DELETE_PRODUCT_SUCCESS,
} from './actions';

const initialState = {
    products: [],
    loading: false,
    error: null,
};

const productReducer = (state = initialState, action) => {
    switch (action.type) {
        case GET_PRODUCTS_REQUEST:
            return {
                ...state,
                loading: true,
            };
        case GET_PRODUCTS_SUCCESS:
            return {
                ...state,
                products: action.payload,
                loading: false,
                error: null,
            };
        case GET_PRODUCTS_FAILURE:
            return {
                ...state,
                loading: false,
                error: action.payload,
            };
        case CREATE_PRODUCT_SUCCESS:
            return {
                ...state,
                products: [...state.products, action.payload],
            };
        case UPDATE_PRODUCT_SUCCESS:
            return {
                ...state,
                products: state.products.map((product) =>
                    product.id === action.payload.id ? action.payload : product
                ),
            };
        case DELETE_PRODUCT_SUCCESS:
            return {
                ...state,
                products: state.products.filter(
                    (product) => product.id !== action.payload
                ),
            };
        default:
            return state;
    }
};

export default productReducer;

Trong đoạn mã trên, chúng ta đã tạo một reducer để xử lý các action liên quan đến sản phẩm. Reducer này sẽ cập nhật trạng thái của ứng dụng theo các action được gửi từ Saga.

Tạo Redux Store và cấu hình Saga

Tiếp theo, trong tệp redux/store.js, chúng ta tạo Redux Store và cấu hình Saga:

import { createStore, applyMiddleware } from 'redux';
import createSagaMiddleware from 'redux-saga';
import rootReducer from './reducers';
import rootSaga from './sagas';

const sagaMiddleware = createSagaMiddleware();

const store = createStore(rootReducer, applyMiddleware(sagaMiddleware));

sagaMiddleware.run(rootSaga);

export default store;

Trong đoạn mã trên, chúng ta đã tạo một Redux Store bằng cách sử dụng createStore() từ Redux. Chúng ta cũng đã tạo một middleware cho Saga bằng createSagaMiddleware() từ Redux Saga và áp dụng nó vào Redux Store bằng applyMiddleware().

Cuối cùng, chúng ta chạy Saga chính bằng cách gọi sagaMiddleware.run(rootSaga).

Tạo Component ProductList

Bây giờ, chúng ta sẽ tạo một component để hiển thị danh sách sản phẩm và cung cấp các chức năng CRUD.

Trong tệp components/ProductList.js, thêm đoạn mã sau:

import React, { useEffect, useState } from 'react';
import { useDispatch, use

Các bạn có thể tham khảo thêm nguồn khác:

How to CRUD using React/Redux/Redux Sagas? - Medium

Basically, I am importing all the sagas into this index file and use 'yield all' inside the 'rootSaga' funcion, which is imported in the store and run. I have a watcher and a bunch of normal sagas....>

React-Redux-Saga: State management of CRUD operations

Sep 12, 2021Redux-Saga is a middleware library used to allow a redux store asynchronously to interact with resources outside of itself. This includes making HTTP requests to external services, accessi>

Redux-A CRUD Example. This article's goal is to explain the… | by ...

Redux-A CRUD Example. This article's goal is to explain the… | by Pratik Chakravorty | codeburst Write Sign up Sign In 500 Apologies, but something went wrong on our end. Refresh the page, check Mediu>

redux-saga examples - CodeSandbox

Redux Saga Examples Learn how to use redux-saga by viewing and forking example apps that make use of redux-saga on CodeSandbox. turing-react-test react-redux-saga-crud silentrobi HellCatVN/get-help we>

React Redux CRUD example with API calls - BezKoder

Oct 12, 2021Redux-Toolkit example with CRUD Application Setup React.js Project Open cmd at the folder you want to save Project folder, run command: npx create-react-app react-redux-crud-example After>

React Redux Saga CRUD App - React.js Examples

Jan 17, 2022React Redux Saga CRUD App Jan 17, 2022 1 min read. REACT CRUD APP. yarn init -y Setup React. yarn add react react-dom react-scripts ... Subscribe to React.js Examples. Get the latest posts>

Redux-Toolkit example with CRUD Application - BezKoder

Sep 29, 2022Redux-Toolkit CRUD example with React Hooks Overview of Redux-Toolkit example with Rest API We will build a React Redux Tutorial Application with API calls in that: Each Tutorial has id, t>

GitHub - diana-moreno/crud-redux-saga

Aug 25, 2021CRUD-REDUX-SAGA Introduction Simple products CRUD developed to learn React Redux with redux-saga. Functional Description A user can: Create Read Update Delete Technical Description Fronten>

GitHub - kuylim/crud-redux-saga

Make sure you have the following installed: Git NodeJs and Npm an IDE to write js code in, for example Webstorm Once your environment is prepared, open a command prompt (terminal) and type in the foll>

CRUD Operation Using React Redux - Part Three

Let's Consider CRUD operations of Employee Module, LIST OF EMPLOYEE ADD EMPLOYEE EDIT EMPLOYEE DELETE EMPLOYEE For a better folder structure you need to create action.js and reducer.js files into the>

How to use Redux-Saga in a React App - Simple Blog Example - Techomoro

Oct 8, 2021How to use Redux-Saga in a React App - Simple Blog Example React It is easier to build web applications with the React library alone. But if the app is getting bigger, we really need a stat>

⚗️ React Redux CRUD app for beginners [with Hooks] - DEV Community

Jan 29, 2021$ npx create-react-app redux-crud-app First let's remove all the files inside the /src folder except for App.js and index.js. Clear out App.js and let's only return a word for now. Run the>

Redux CRUD Tutorial | Tech&Startup

You may find the World's Simplest Redux with APIs Example to be a good introduction. Build an API Back End For a CRUD application we need to build an API on the server to interact with the database. T>

An example react-redux-saga CRUD application | LaptrinhX

An example CRUD application for managing blog posts. Built with React, Redux and Redux Saga on the client side. The REST API server was generated with loopback.io and uses an in-memory database at run>

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>

Redux-saga and Typescript, doing it right. - Lalilo

This example will not compile since there's a conflict on the type of bar: 1function* thisIsAWrongSaga(foo: string): Generator { 2 const bar: string = yield "baz"; 3 4 console>

CRUD Operation Using React Redux - Part One

We will learn the React-Redux structure step-by-step by separating it into three parts. Part 1: Install & Configure React Application. Part 2: Configure Redux structure in React App. Part 3: Perform C>

reactjs - Implementing CRUD with react-redux - Stack Overflow

Sep 18, 20212. Handling CRUD operations like this is - for examples - handled by "RTK Query" of the official Redux Toolkit, which generates all the actions, reducers etc. for you. It also handles stuf>

Implement Redux-Saga in your React TypeScript Project.

Apr 12, 2021Mastering Redux with Redux toolkit, write a correct redux! Jakub Kozak in Geek Culture Stop Using "&&" for Conditional Rendering in React Without Thinking Jonathan in Dev Genius You Don't.>

Redux saga & redux toolkit - Stack Overflow

I also include helpers to facilitate some of the stuff you're doing by including an axios wrapper that ties in with saga's task cancellation, stream lines request lifecycles, and builds default CRUD m>

Redux-Saga - An intuitive Redux side effect manager. | Redux-Saga - js

Example Usage 1. Dispatch an action 2. Initiate a side effect 3. Connect to the store Suppose we have a UI to fetch some user data from a remote server when a button is clicked. (For brevity, we'll ju>

How To Use Redux Saga/Typescript Like a pro! I - Medium

The mental model is that a saga is like a separate thread in your application that's solely responsible for side effects. redux-saga is a redux middleware, which means this thread can be started, paus>

Redux-Saga tutorial for beginners and dog lovers | HackerNoon

I began using redux-saga at work in a fairly complex boilerplate . Start Writing. Notifications. see more. LOGIN / SIGNUP. Redux-Saga tutorial for beginners and dog lovers by @ryanjyost. 80,813 reads.>

react-redux-crud - An example react-redux-saga CRUD application

An example CRUD application for managing blog posts. Built with React, Redux and Redux Saga on the client side. The REST API server was generated with loopback.io and uses an in-memory database at run>

Redux Saga Tutorial | Simple Example | React Redux series Part 8

Redux-saga Explained , How to handle Asynchronous Actions with Redux saga Middleware using Generator Functions and yield. Keywords : Redux for beginners, R...>

How to Implement Redux-Saga With ReactJS and Redux [TUTORIAL] - Duomly

Redux Saga. The next solution for middleware is Redux-Saga. Redux-Saga uses ES6 Generators instead of functions. It allows us to easily test, write, and read the asynchronous calls in Redux. The big a>

react-redux examples - CodeSandbox

Learn how to use react-redux by viewing and forking example apps that make use of react-redux on CodeSandbox. redux-essentials-counter-example. todos. redux-essentials-example. todomvc. real-world. co>

Redux saga crud example Jobs, Employment | Freelancer

Search for jobs related to Redux saga crud example or hire on the world's largest freelancing marketplace with 20m+ jobs. It's free to sign up and bid on jobs.>


Tags: