2016-06-12 9 views
29

Wie kann ich auf den Redux-Status innerhalb einer Saga-Funktion zugreifen?Wie bekomme ich etwas vom Staat/Geschäft in eine Redux-Saga-Funktion?

Mein Problem

Ich habe eine Anwendung, bestehend aus folgenden Teilen:

  TOOLBAR   
--------------------------------- 
User info  | Current Project 

Jeder Teil ist eine andere Komponente mit einem eigenen Druckminderer, Saga, Aktionen und Staat.

Die Symbolleiste verfügt über eine Schaltfläche zum Speichern, mit der der Aktionstyp "SAVE_PROJECT" ausgelöst wird. Das Problem ist, dass ich nicht möchte, dass die Symbolleiste das Projekt kennt (es hat mehr Verantwortlichkeiten und ich möchte nur, dass es Aktionen mit dem Typ versendet).

Ich habe ein Projekt im Zusammenhang Saga, die auf den „SAVE_PROJECT“ hört:

... 
export function* saveProjectTask() { 
    while(true) { 
    yield take(SAVE_PROJECT); 
    let project = /* THIS IS THE PROBLEM, I DON'T HAVE THE PROJECT */; 
    yield call(fetch, '/api/project', { body: project, method: 'PUT' }); 
    yield put({type: SAVE_PROJECT_SUCCESS}); 
    } 
} 

Ich kann nicht das Projekt von dem Redux Zustand im Innern der Saga bekommen.

Ich glaube nicht, dass ich auf das "SAVE_PROJECT" -Ereignis innerhalb des Curren-Projekt-Reduzierers hören kann und dann innerhalb des Reduzierers das Projekt bekomme und eine andere Aktion mit dem Projekt absende.

Ich möchte wirklich nicht, dass meine Symbolleiste den gesamten Statusbaum kennt und für jede Aktion etwas zu der Aktion sendet.

Wie kann ich den Staat selbst an die Sage weitergeben? Oder nur der relevante Teil des Staates?

Antwort

74

Wie @markerikson schon sagt, macht redux-saga eine sehr nützliche API select() für immer einen Teil davon ein selector über den Zustand aufzurufen in der Saga verfügbar.

Für Ihr Beispiel eine einfache Implementierung könnte 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}); 
    } 
} 

Neben dem vorgeschlagenen doc von @markerikson, ist es eine sehr gute video tutorial von D. Abramov, die erklärt, wie selectors mit Redux verwenden. Überprüfen Sie auch this interessanten Thread auf Twitter.

+2

Genau was ich wollte .. Ich kann nicht glauben, ich habe es verpasst –

9

Dies ist, wofür "Selektor" -Funktionen sind. Du übergibst ihnen den ganzen Staatsbaum und sie bringen ein Stück des Staates zurück. Der Code, der den Selektor aufruft, muss nicht wissen wo in dem Zustand, dass Daten war, nur, dass es zurückgegeben wurde. 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.