Редукс Сага
Redux Saga — это библиотека промежуточного программного обеспечения для Redux, которая позволяет вам управлять побочными эффектами (например, асинхронными запросами API) более организованным и декларативным способом. Вот краткое руководство по использованию Redux Saga:
- Установить Редукс Сага
npm install redux-saga
2. Создайте сагу Сага — это функция, которая прослушивает действие и выполняет некоторый побочный эффект. Чтобы создать Saga, вам нужно определить функцию генератора, используя синтаксис function*
.
import { takeEvery, put, call } from 'redux-saga/effects'; import { fetchSuccess, fetchError } from './actions'; import { FETCH_DATA } from './constants'; import api from './api'; function* fetchData() { try { const data = yield call(api.fetchData); yield put(fetchSuccess(data)); } catch (error) { yield put(fetchError(error)); } } function* mySaga() { yield takeEvery(FETCH_DATA, fetchData); } export default mySaga;
В этом примере мы определяем сагу с именем fetchData
. Эта сага прослушивает действие FETCH_DATA
и выполняет вызов API, используя эффект call
. Если вызов API успешен, он отправляет действие fetchSuccess
, используя эффект put
. Если есть ошибка, он отправляет действие fetchError
, используя эффект put
.
Функция mySaga
— это корневая сага, которую мы будем использовать для запуска всех наших саг. В этом примере мы используем эффект takeEvery
для прослушивания всех действий FETCH_DATA
и вызова саги fetchData
.
3. Используйте промежуточное ПО Saga. Чтобы использовать промежуточное ПО Saga, вам необходимо применить его к вашему магазину Redux при его создании.
import { createStore, applyMiddleware } from 'redux'; import createSagaMiddleware from 'redux-saga'; import rootReducer from './reducers'; import mySaga from './sagas'; const sagaMiddleware = createSagaMiddleware(); const store = createStore( rootReducer, applyMiddleware(sagaMiddleware) ); sagaMiddleware.run(mySaga); export default store;
В этом примере мы создаем хранилище Redux и применяем промежуточное ПО Saga, используя applyMiddleware
. Мы также передаем нашу корневую сагу методу run
промежуточного программного обеспечения, который запускает сагу и слушает все действия, которые необходимо обработать.
Вот и все! С помощью этих простых шагов вы можете начать использовать Redux Saga для управления побочными эффектами в вашем приложении Redux. Конечно, с Redux Saga вы можете делать гораздо больше, например, использовать другие эффекты, такие как takeLatest
, fork
или select
. Но это краткое руководство должно дать вам хорошее представление о том, с чего начать.
4. Действия по отправке Теперь, когда мы определили нашу Saga и применили промежуточное программное обеспечение, мы можем отправлять действия из наших компонентов, чтобы вызвать побочный эффект. Например, предположим, что у нас есть компонент, которому нужно получить некоторые данные из API при его монтировании.
import React, { useEffect } from 'react'; import { connect } from 'react-redux'; import { fetchData } from './actions'; function MyComponent({ fetchData }) { useEffect(() => { fetchData(); }, []); return ( <div> {/* render component */} </div> ); } export default connect(null, { fetchData })(MyComponent);
В этом примере мы определяем компонент с именем MyComponent
и используем хук useEffect
для отправки действия fetchData
при монтировании компонента. Мы подключаем компонент к хранилищу Redux с помощью функции connect
из библиотеки react-redux
и сопоставляем действие fetchData
со свойствами компонента.
Когда отправляется действие fetchData
, ПО промежуточного слоя Saga перехватывает его и запускает fetchData
Saga, которая выполняет вызов API и отправляет соответствующие действия на основе результата.
5. Тестируйте саги Наконец, важно протестировать саги, чтобы убедиться, что они работают должным образом. Redux Saga предоставляет утилиту для тестирования под названием redux-saga-test-plan
, которая упрощает тестирование ваших саг.
import { expectSaga } from 'redux-saga-test-plan'; import { fetchData, fetchSuccess } from './actions'; import { fetchData as fetchDataSaga } from './sagas'; import api from './api'; it('fetches data from API and dispatches success action', () => { const data = [1, 2, 3]; const action = fetchData(); return expectSaga(fetchDataSaga, action) .provide([ [call(api.fetchData), data], ]) .put(fetchSuccess(data)) .run(); });
В этом примере мы определяем тест, который проверяет, извлекает ли fetchData
Saga данные из API и отправляет действие fetchSuccess
. Мы используем функцию expectSaga
из redux-saga-test-plan
для тестирования Saga и предоставляем фиктивную реализацию вызова API с использованием метода provide
.
Redux Saga — это мощная библиотека промежуточного программного обеспечения, которая упрощает управление побочными эффектами в вашем приложении Redux. Определив саги, которые обрабатывают определенные действия, вы можете сделать свой код организованным и простым для понимания. С помощью библиотеки redux-saga
и утилит тестирования, таких как redux-saga-test-plan
, вы можете создавать надежные и надежные приложения, которые легко обрабатывают асинхронные действия.
Расширенное использование
Хотя предыдущих шагов должно быть достаточно, чтобы начать использовать Redux Saga, есть некоторые более продвинутые функции, которые могут помочь вам справиться с более сложными вариантами использования.
Разветвление саг: саги могут быть разветвлены для запуска независимо друг от друга. Это полезно, когда вам нужно одновременно обрабатывать несколько асинхронных действий.
import { take, fork } from 'redux-saga/effects'; function* watchAndLog() { while (true) { const action = yield take('*'); console.log('action', action); } } function* rootSaga() { yield fork(watchAndLog); }
В этом примере мы определяем Saga с именем watchAndLog
, которая регистрирует все действия, отправленные на консоль. Мы используем эффект fork
для запуска этой саги независимо от других саг в корневой саге.
- Объединение саг: саги можно комбинировать с помощью эффекта
all
для обработки нескольких действий в одной саге.
import { all, call, put, takeEvery } from 'redux-saga/effects'; function* fetchData(action) { try { const data = yield call(api.fetchData, action.payload); yield put(fetchSuccess(data)); } catch (error) { yield put(fetchError(error)); } } function* postData(action) { try { const response = yield call(api.postData, action.payload); yield put(postSuccess(response)); } catch (error) { yield put(postError(error)); } } function* rootSaga() { yield all([ takeEvery(FETCH_DATA, fetchData), takeEvery(POST_DATA, postData), ]); }
В этом примере мы определяем две саги с именами fetchData
и postData
, которые обрабатывают действия FETCH_DATA
и POST_DATA
соответственно. Мы используем эффект takeEvery
, чтобы прослушивать эти действия и вызывать соответствующие саги. Затем мы используем эффект all
, чтобы объединить эти саги в одну корневую сагу.
- Отмена Саги: Саги можно отменить с помощью эффекта
cancel
. Это полезно, когда вам нужно остановить запуск саги в ответ на определенное действие.
import { take, call, cancel, fork } from 'redux-saga/effects'; function* watchFetchData() { while (true) { const { payload } = yield take(FETCH_DATA); const task = yield fork(fetchData, payload); yield take(CANCEL_FETCH_DATA); yield cancel(task); } } function* fetchData(payload) { // fetch data } function* rootSaga() { yield fork(watchFetchData); }
В этом примере мы определяем сагу с именем watchFetchData
, которая прослушивает действие FETCH_DATA
и разветвляет сагу fetchData
для ее обработки. Мы используем эффект take
, чтобы прослушивать действие CANCEL_FETCH_DATA
, и эффект cancel
, чтобы остановить запуск саги fetchData
.
Заключение
Redux Saga предоставляет множество мощных функций для управления побочными эффектами в вашем приложении Redux. Комбинируя саги и используя расширенные эффекты, такие как fork
, all
и cancel
, вы можете с легкостью обрабатывать сложные асинхронные потоки. С помощью библиотеки redux-saga
и утилит тестирования, таких как redux-saga-test-plan
, вы можете создавать надежные и надежные приложения, которые легко обрабатывают асинхронные действия.