Wie bekomme ich etwas aus dem Staat / Laden in einer Redux-Saga-Funktion?

120

Wie greife ich innerhalb einer Saga-Funktion auf den Redux-Status zu?

Kurze Antwort:

import { select } from 'redux-saga/effects';
...
let data = yield select(stateSelectorFunction);
Adam Tal
quelle

Antworten:

209

Wie @markerikson bereits sagt, redux-sagastellt eine sehr nützliche API select()zur Verfügung, mit der ein Status aufgerufen werden kann , um einen selectorTeil davon in der Saga verfügbar zu machen.

Für Ihr Beispiel könnte eine einfache Implementierung sein:

/*
 * 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});
  }
}

Zusätzlich zu dem vorgeschlagenen doc von @markerikson, ist es eine sehr gute Video - Tutorial von D. Abramov , die erklärt , wie die Verwendung selectorsmit Redux. Überprüfen Sie auch diesen interessanten Thread auf Twitter.

NickGnd
quelle
3
Genau das, was ich wollte. Ich kann nicht glauben, dass ich es verpasst habe
Adam Tal
28

Dafür sind "Selektor" -Funktionen gedacht. Sie übergeben ihnen den gesamten Statusbaum und sie geben einen Teil des Status zurück. Der Code, der den Selektor aufruft, muss nicht wissen, wo sich die Daten befanden, sondern nur, dass sie zurückgegeben wurden. Einige Beispiele finden Sie unter http://redux.js.org/docs/recipes/ComputingDerivedData.html .

Innerhalb einer Saga kann die select()API verwendet werden, um einen Selektor auszuführen.

markerikson
quelle
Es ist interessant, wie dies 3,5 Stunden vor der akzeptierten Antwort geschrieben wurde, aber es gab kein Beispiel, so dass es nicht akzeptiert wurde. Trotzdem Danke!
Aleksandar
1
@Casper - ich stimme zu! Es geht aber nicht darum, wie schnell Sie hier eine Frage beantworten, sondern wie gut Ihre Antwort ist. Ich denke, Antworten müssen einfach und leicht lesbar sein. Diese Antwort stimmte nicht überein und die akzeptierte Antwort war viel einfacher zu verstehen.
Adam Tal
@ AdamTal ja, ich stimme zu :)
Aleksandar
2

Ich habe einen eventChannel verwendet, um eine Aktion von einem Rückruf innerhalb der Generatorfunktion auszulösen

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)
    }
}
yardenapp
quelle