Ответы:
Как уже сказал @markerikson, redux-saga
предоставляет очень полезный API select()
для вызова selector
состояния, чтобы часть его была доступна внутри саги.
Для вашего примера простая реализация может быть:
/*
* Selector. The query depends by the state shape
*/
export const getProject = (state) => state.project
// Saga
export function* saveProjectTask() {
while(true) {
yield take(SAVE_PROJECT);
let project = yield select(getProject); // <-- get the project
yield call(fetch, '/api/project', { body: project, method: 'PUT' });
yield put({type: SAVE_PROJECT_SUCCESS});
}
}
В дополнение к предложенному документу @markerikson есть очень хороший видеоурок от Д. Абрамова, в котором объясняется, как использовать selectors
с Redux. Также проверьте эту интересную ветку в Twitter.
Вот для чего нужны "селекторные" функции. Вы передаете им все дерево состояний, и они возвращают некоторую часть состояния. Код , который вызывает селектор не нужно знать , где в состоянии , что данные были, только что он был возвращен. См. Http://redux.js.org/docs/recipes/ComputingDerivedData.html для некоторых примеров.
В саге select()
API можно использовать для выполнения селектора.
Я использовал eventChannel для отправки действия из обратного вызова в функции генератора
import {eventChannel} from 'redux-saga';
import {call, take} from 'redux-saga/effects';
function createEventChannel(setEmitter) {
return eventChannel(emitter => {
setEmitter(emitter)
return () => {
}
}
)
}
function* YourSaga(){
let emitter;
const internalEvents = yield call(createEventChannel, em => emitter = em)
const scopedCallback = () => {
emitter({type, payload})
}
while(true){
const action = yield take(internalEvents)
yield put(action)
}
}