Risposte:
Come già dice @markerikson, redux-saga
espone un'API molto utile select()
per invocare uno selector
stato sullo stato per averne una parte disponibile all'interno della saga.
Per il tuo esempio una semplice implementazione potrebbe essere:
/*
* 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});
}
}
Oltre al documento suggerito da @markerikson, c'è un ottimo video tutorial di D. Abramov che spiega come usarlo selectors
con Redux. Controlla anche questo interessante thread su Twitter.
A questo servono le funzioni di "selettore". Gli passi l'intero albero dello stato e loro restituiscono un pezzo dello stato. Il codice che chiama il selettore non ha bisogno di sapere dove si trovavano i dati nello stato, ma solo che erano stati restituiti. Vedi http://redux.js.org/docs/recipes/ComputingDerivedData.html per alcuni esempi.
All'interno di una saga, l' select()
API può essere utilizzata per eseguire un selettore.
Ho usato un eventChannel per inviare un'azione da un callback all'interno della funzione del generatore
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)
}
}