Відповіді:
Як вже говорить @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)
}
}