Respostas:
Como @markerikson já diz, redux-saga
expõe uma API muito útil select()
para invocar um selector
on 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 selectors
com 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)
}
}