Respostas:
Como @markerikson já diz, redux-sagaexpõe uma API muito útil select()para invocar um selectoron the state para obter alguma parte dele disponível dentro da saga.
Para seu exemplo, uma implementação simples poderia ser:
/*
* 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});
}
}
Além do documento sugerido por @markerikson, há um vídeo tutorial muito bom de D. Abramov que explica como usar selectorscom o Redux. Verifique também este tópico interessante no Twitter.
É para isso que servem as funções de "seletor". Você passa para eles toda a árvore de estado e eles retornam alguma parte do estado. O código que chama o selector não precisa saber onde no estado que os dados foi, apenas que ele foi devolvido. Veja http://redux.js.org/docs/recipes/ComputingDerivedData.html para alguns exemplos.
Dentro de uma saga, a select()API pode ser usada para executar um seletor.
Eu usei um eventChannel para despachar uma ação de um retorno de chamada dentro da função do gerador
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)
}
}