2016-07-13 16 views
2

Ich versuche, React-Boilerplate mit Redux-Saga innen zu implementieren. Also versuche ich einige Daten vom Server zu holen und dann auf eine andere Seite umzuleiten. Das Problem ist, dass vor der Umleitung Saga eine zweite Anfrage an den Server macht. Ich denke, es ist etwas falsch mit dem Abbrechen. Hier ist ein Teil meiner Code ist:Redux-Saga ruft Aktion nach Abbrechen

export function* fetchData() { 
    ... 
    console.log('fetched'); 
    yield browserHistory.push('/another-page'); 
} 

export function* fetchDataWatcher() { 
    while (yield take('FETCH_DATA')) { 
    yield call(fetchData); 
    } 
} 

export function* fetchDataRootSaga() { 
    const fetchWatcher = yield fork(fetchDataWatcher); 

    yield take(LOCATION_CHANGE); 
    yield cancel(fetchWatcher); 
} 

export default [ 
    fetchDataRootSaga 
] 

So in diesem Beispiel habe ich zwei Konsolenprotokolle, erscheint die zweite vor umleitet. Wie kann ich es reparieren?

Und eine andere Frage. Eigentlich habe ich mehr Funktionen in dieser Datei. Sollte ich "rootSaga" für jeden von ihnen erstellen oder ich kann sie alle in diesem fetchDataRootSaga() abbrechen? Ich meine, ist es normal, wenn ich Sagen auf diese Weise annulliere:

export function* fetchDataRootSaga() { 
    const watcherOne = yield fork(fetchDataOne); 
    const watcherTwo = yield fork(fetchDataTwo); 
    ... 

    yield take(LOCATION_CHANGE); 
    yield cancel(watcherOne); 
    yield cancel(watcherTwo); 
    ... 
} 

Vielen Dank im Voraus! P.S. Ich bin mir nicht sicher, ob dieser Code Best Practices ist. Es ist inspiriert von this repository

Antwort

0

Dies vereitelt den Zweck der Saga, die möglicherweise lange laufenden asynchronen Anfragen und Rücksendungen zu behandeln ist. Sie könnten stattdessen einen Zustand, in Ihrem redux Speicher gesetzt wie so

export function* fetchData() { 
    ... 
    console.log('fetched'); 
    yield put(setRedirectState('/another-page')); 
} 

Dann sehen, ob die Umleitung Zustand in Ihrem Container in ComponentWillUpdate gesetzt ist und entsprechend zu so etwas wie diese

import { push } from 'react-router-redux'; 
dispatch(push(state.redirecturl)) 

Ich habe umleiten nicht versuchte dies, aber die Erfahrung, die ich mit React-Boilerplate habe, ist das, was ich zuerst versuchen würde.

+0

Ich habe genau wie du geschrieben, aber es gibt immer noch doppelte Anfrage an den Server. – th1rt3nth

+0

Haben Sie überprüft, dass Sie die Aktion 'FETCH_DATA' nicht zweimal gesendet haben, was die Saga zweimal auslösen würde? Was passiert, wenn Sie take() zu takeLatest() ändern? – garajo

1

Vielleicht durch Einstellen der Schleife innerhalb fetchDataWatcher beginnen ein wenig mehr wie diese Sie

export function* fetchDataWatcher() { 
    while (true) { 
    yield take('FETCH_DATA'); 
    yield call(fetchData); 
    } 
} 

auch aussehen können die Routen besser durch so etwas wie dies vielleicht tun

import { push } from 'react-router-redux'; 
import { put } from 'redux-saga/effects'; 

export function* fetchData() { 
    ... 
    console.log('fetched'); 
    yield put(push('/another-page')); 
} 

Insgesamt würde ich auf put zögern eine route change und dann ganz separat eine take drauf, nur wenn du bei allen location changes abbrechen willst (aber ich gehe mal davon aus, dass du hinterher willst :))

Verwandte Themen