Respuestas:
Como ya dice @markerikson, redux-saga
expone una API muy útil select()
para invocar un selector
estado para obtener una parte de ella disponible dentro de la saga.
Para su ejemplo, una implementación simple podría 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});
}
}
Además del documento sugerido por @markerikson, hay un muy buen video tutorial de D. Abramov que explica cómo usar selectors
Redux. Consulta también este interesante hilo en Twitter.
Para eso sirven las funciones de "selector". Les pasas todo el árbol del estado y te devuelven una parte del estado. El código que llama al selector no necesita saber en qué estado del estado estaban los datos, solo que se devolvió. Consulte http://redux.js.org/docs/recipes/ComputingDerivedData.html para ver algunos ejemplos.
Dentro de una saga, la select()
API se puede utilizar para ejecutar un selector.
Usé un eventChannel para enviar una acción desde una devolución de llamada dentro de la función del generador
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)
}
}