Ранее мы объяснили основное использование фреймворка redux и dva framework, поскольку модуль эффектов в фреймворке dva предназначен для получения знаний в redux-saga, некоторые студенты могут использовать фреймворк dva, но они не очень хорошо знакомы с redux-saga. Сегодня давайте кратко объясним основной API фреймворка saga и как его использовать с фреймворком redux.
официальный адрес redux-saga
Leon is .com / горячее цинкование - Saha - ...
Демонстрация запущенных рендеров
- todoList
- CounterApp
Образец демонстрационного адреса
Автор redux-saga-Demo по-прежнему предоставляет две разные версии в соответствии с предыдущим стилем, простой CounterApp и чуть более сложный TodoList.
- CounterApp
- todoList
что такое редукс-сага
redux-saga — это промежуточное ПО (также известное как асинхронное действие) для управления асинхронными действиями в приложениях Redux. Redux-saga собирает всю логику асинхронных операций в одном месте, создавая Sagas, которые можно использовать для замены промежуточного программного обеспечения redux-thunk.
Это означает, что логика приложения будет существовать в двух местах:
-
Редукторы отвечают за обработку обновлений состояния для действий.
-
Саги отвечают за координацию сложных или асинхронных операций.
Саги создаются с помощью функции генератора.Если вы не знакомы с функцией генератора,Пожалуйста, ознакомьтесь с введением г-на Руана в Генератор.
Sagas отличается от thunks, thunks вызываются при создании действия, а Sagas будут вызываться только при запуске приложения (но первоначальный запуск Sagas может вызывать другие Sagas динамически), Sagas можно рассматривать как процесс, работающий в фоновом режиме, Саги Слушайте инициированное действие, а затем решайте, что делать на основе этого действия: инициировать ли асинхронный вызов (например, запрос на выборку), или инициировать другие действия в Магазине, или даже вызывать другие Саги.
В мире redux-saga все задачи выполняются в общих эффектах yield (Effect можно рассматривать как единицу задачи redux-saga). Эффекты — это простые объекты Javascript, которые содержат информацию для выполнения промежуточным программным обеспечением Saga (например, вы можете видеть, что действия Redux на самом деле являются объектами, содержащими информацию о выполнении), redux-saga предоставляет различные задачи для каждой задачи. функция, инициирующая действие в Магазине, инициирующая фоновую задачу или ожидающая будущего действия, которое удовлетворяет определенным условиям
API ядра фреймворка Redux-saga
1. Вспомогательная функция Саги
redux-saga предоставляет некоторые вспомогательные функции для получения задач, когда в магазине инициируются определенные действия.Позвольте мне сначала объяснить две вспомогательные функции:takeEvery
а такжеtakeLatest
- takeEvery
Например: каждый раз, когда нажимается кнопка Fetch, мы инициируем действие FETCH_REQUESTED. Мы хотим обработать это действие, запустив задачу для получения некоторых данных с сервера.
Сначала мы создаем задачу, которая будет выполнять асинхронное действие:
import { call, put } from 'redux-saga/effects'
export function* fetchData(action) {
try {
const data = yield call(Api.fetchUser, action.payload.url);
yield put({type: "FETCH_SUCCEEDED", data});
} catch (error) {
yield put({type: "FETCH_FAILED", error});
}
}
Затем запускайте указанную выше задачу каждый раз, когда запускается действие FETCH_REQUESTED.
import { takeEvery } from 'redux-saga'
function* watchFetchData() {
yield* takeEvery("FETCH_REQUESTED", fetchData)
}
Уведомление: Вышеупомянутая функция takeEvery может быть заменена следующей записью
function* watchFetchData() {
while(true){
yield take('FETCH_REQUESTED');
yield fork(fetchData);
}
}
- takeLatest
В приведенном выше примере takeEvery позволяет запускать несколько экземпляров fetchData одновременно, и в определенный момент мы можем запустить новую задачу fetchData, даже если есть одна или несколько fetchData до ее завершения.
Если мы хотим получить только последний ответ на этот запрос (например, всегда показывать последнюю версию данных), мы можем использовать вспомогательную функцию takeLatest.
import { takeLatest } from 'redux-saga'
function* watchFetchData() {
yield* takeLatest('FETCH_REQUESTED', fetchData)
}
В отличие от takeEvery, takeLatest позволяет выполнять только одну задачу fetchData в любой момент времени, и эта задача запускается последней.Если перед этим уже выполнялась задача, предыдущая задача будет автоматически отменена.
2. Создатели эффектов
Фреймворк redux-saga предоставляет множество функций для создания эффектов, кратко представим наиболее часто используемые в разработке.
- take(pattern)
- put(action)
- call(fn, ...args)
- fork(fn, ...args)
- select(selector, ...args)
take(pattern)
Функцию взятия можно понимать как отслеживание будущих действий.Она создает объект команды и указывает промежуточному ПО ожидать определенного действия.Генератор приостанавливается до тех пор, пока не будет инициировано действие, соответствующее шаблону, и будет продолжать выполняться следующий оператор, который то есть взять блокирующий эффект
Применение:
function* watchFetchData() {
while(true) {
// 监听一个type为 'FETCH_REQUESTED' 的action的执行,直到等到这个Action被触发,才会接着执行下面的 yield fork(fetchData) 语句
yield take('FETCH_REQUESTED');
yield fork(fetchData);
}
}
put(action)
Функция put используется для отправки эффекта действия.Вы можете просто понять это как функцию отправки в среде редукции.Когда действие помещено, редюсер вычислит новое состояние и вернет его.Уведомление:put также является блокирующим эффектом
Применение:
export function* toggleItemFlow() {
let list = []
// 发送一个type为 'UPDATE_DATA' 的Action,用来更新数据,参数为 `data:list`
yield put({
type: actionTypes.UPDATE_DATA,
data: list
})
}
call(fn, ...args)
Вы можете просто понимать функцию вызова как функцию, которая может вызывать другие функции.Он инструктирует промежуточное ПО вызывать функцию fn, а args являются параметрами функции.Уведомление:Функция fn может быть функцией-генератором или обычной функцией, которая возвращает обещание, а функция вызова также является блокирующим эффектом.
Применение:
export const delay = ms => new Promise(resolve => setTimeout(resolve, ms))
export function* removeItem() {
try {
// 这里call 函数就调用了 delay 函数,delay 函数为一个返回promise 的函数
return yield call(delay, 500)
} catch (err) {
yield put({type: actionTypes.ERROR})
}
}
fork(fn, ...args)
Функция fork очень похожа на функцию call, обе из которых используются для вызова других функций, но функция fork является неблокирующей функцией, то есть после выполнения программы.yield fork(fn, args)
После этой строки кода следующая строка оператора кода будет выполнена немедленно, вместо того, чтобы ждать, пока функция fn вернет результат, будет выполнен следующий оператор
Применение:
import { fork } from 'redux-saga/effects'
export default function* rootSaga() {
// 下面的四个 Generator 函数会一次执行,不会阻塞执行
yield fork(addItemFlow)
yield fork(removeItemFlow)
yield fork(toggleItemFlow)
yield fork(modifyItem)
}
select(selector, ...args)
Функция select используется для указания промежуточному программному обеспечению вызывать предоставленный селектор для получения данных о состоянии в Store.Вы также можете просто понимать это как ту же функцию, что и получение данных о состоянии в хранилище в среде избыточности:store.getState()
Применение:
export function* toggleItemFlow() {
// 通过 select effect 来获取 全局 state上的 `getTodoList` 中的 list
let tempList = yield select(state => state.getTodoList.list)
}
3. создатьSagaMiddleware()
Функция createSagaMiddleware используется для создания промежуточного программного обеспечения Redux, которое связывает Sagas с Redux Store.
Каждая функция в сагах должна возвращать объект Generator, а промежуточное ПО будет перебирать Генератор и выполнять все полученные эффекты (Эффекты можно рассматривать как единицу задачи Redux-saga).
Применение:
import {createStore, applyMiddleware} from 'redux'
import createSagaMiddleware from 'redux-saga'
import reducers from './reducers'
import rootSaga from './rootSaga'
// 创建一个saga中间件
const sagaMiddleware = createSagaMiddleware()
// 创建store
const store = createStore(
reducers,
将sagaMiddleware 中间件传入到 applyMiddleware 函数中
applyMiddleware(sagaMiddleware)
)
// 动态执行saga,注意:run函数只能在store创建好之后调用
sagaMiddleware.run(rootSaga)
export default store
4. middleware.run(sagas,...args)
Динамическое выполнение саг, используемое для выполнения саг после этапа применения промежуточного программного обеспечения.
- саги: Функция: Генератор функции
- args: Массив: Аргументы, предоставленные саге (кроме метода getState Store)
Примечание. Динамически выполнять оператор сагиmiddleware.run(sagas)
Она должна выполняться после создания хранилища, если выполнить до создания хранилища, программа сообщит об ошибке
Возьмите демо-версию CounterApp, чтобы увидеть, как используется redux-saga
**index.js **
import React from 'react';
import ReactDOM from 'react-dom';
import {createStore, applyMiddleware} from 'redux'
import createSagaMiddleware from 'redux-saga'
import rootSaga from './sagas'
import Counter from './Counter'
import rootReducer from './reducers'
const sagaMiddleware = createSagaMiddleware()
let middlewares = []
middlewares.push(sagaMiddleware)
const createStoreWithMiddleware = applyMiddleware(...middlewares)(createStore)
const store = createStoreWithMiddleware(rootReducer)
sagaMiddleware.run(rootSaga)
const action = type => store.dispatch({ type })
function render() {
ReactDOM.render(
<Counter
value={store.getState()}
onIncrement={() => action('INCREMENT')}
onDecrement={() => action('DECREMENT')}
onIncrementAsync={() => action('INCREMENT_ASYNC')} />,
document.getElementById('root')
)
}
render()
store.subscribe(render)
sagas.js
import { put, call, take,fork } from 'redux-saga/effects';
import { takeEvery, takeLatest } from 'redux-saga'
export const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
function* incrementAsync() {
// 延迟 1s 在执行 + 1操作
yield call(delay, 1000);
yield put({ type: 'INCREMENT' });
}
export default function* rootSaga() {
// while(true){
// yield take('INCREMENT_ASYNC');
// yield fork(incrementAsync);
// }
// 下面的写法与上面的写法上等效
yield* takeEvery("INCREMENT_ASYNC", incrementAsync)
}
reducer.js
export default function counter(state = 0, action) {
switch (action.type) {
case 'INCREMENT':
return state + 1
case 'DECREMENT':
return state - 1
case 'INCREMENT_ASYNC':
return state
default:
return state
}
}
Как видно из приведенной выше структуры кода, использование redux-saga относительно простое, по сравнению с CounterApp предыдущего фреймворка redux, здесь есть дополнительный файл sagas, а файл reducers по-прежнему используется раньше.
Суммировать
В этой статье объясняются в основном общие API, которые чаще всего используются при разработке фреймворка redux-saga, и есть много менее часто используемых API, пожалуйста, обратитесь к официальной документации redux-saga:Леон is.com/HDG-Saga-…
Если студенты видят статью здесь, они все еще не знакомы с основами использования фреймворка redux-saga, а концепции расплывчаты.Рекомендуется взглянуть на демо-пример, предоставленный автором.
Предложение автора: Учащиеся могут поделиться тем, что автор объяснил ранее.редукционная структураСравните с фреймворком redux-saga, чтобы научиться понимать, чтобы различия и связи между ними были яснее.
время благосостояния
- Адрес OneM авторского проекта с открытым исходным кодом React Native (разработан путем построения фреймворка в соответствии со стандартами корпоративной разработки):GitHub.com/LightIntensity-…: добро пожаловать друзьяstar
- Краткая домашняя страница автора: содержит более 60 технических статей, связанных с разработкой RN.у-у-у. Краткое описание.com/U/023338566…Добро пожаловать друзья:уделять больше внимания,как более
- Автор группы технического обмена React Native QQ:620792950Приглашаем друзей присоединиться к группе для обмена и обучения
- дружеское напоминание:При разработке возникли технические проблемы, связанные с RN, и друзья могут присоединиться к группе обмена (620792950), задавайте вопросы в группе, общайтесь и учитесь друг у друга. Группа обмена также регулярно обновляет последние учебные материалы RN для всех, спасибо за вашу поддержку!