2016-05-10 8 views
10

Ich arbeitete an einem React & Redux-Projekt. Das Projekt verwendete die Verwendung von Webpack-Dev-Middleware und Hot Middleware zum Warmladen.Redux Saga heiß nachladen

Nachdem ich Redux Saga zu dem Projekt hinzugefügt und Saga Middleware zum Redux-Shop hinzugefügt habe. Es scheint, dass, wenn ich die Saga-Codes zu ändern, der heiße Nachladen Wille brach und eine Fehlermeldung angezeigt:

Provider> nicht unterstützt store on the fly ändern. Es ist sehr wahrscheinlich, dass Sie diesen Fehler sehen, da Sie auf Redux 2.x und React Redux 2.x aktualisiert haben, die Reduktoren nicht mehr automatisch neu laden. Die Migrationsanweisungen finden Sie unter https://github.com/reactjs/react-redux/releases/tag/v2.0.0.

Ich verstehe, dass Saga Generatoren verwendet und es ist zeitabhängig. Ist es möglich, die Seite mit Sagas neu zu laden? Genauso wie Redux Reduktoren sich beim Warmladen ersetzen.

Danke!

+0

Siehe Diskussion https://github.com/yelouafi/redux-saga/issues/22#issuecomment-218522365 –

Antwort

16

Ich arbeite an einem Projekt mit Redux und Redux-Saga (aber nicht reagieren). Ich habe das heiße Nachladen von Sagas mit sagaMiddleware.run() implementiert, aber Sie müssen das Modul neu laden und Reduktoren und Sagen ersetzen, wie in dem von Ihnen angegebenen Link angegeben (https://github.com/reactjs/react-redux/releases/tag/v2.0.0).

import { createStore } from 'redux'; 
import rootReducer from '../reducers/index'; 
import getSagas from '../sagas'; 

export default function configureStore(initialState) { 
    const sagaMiddleware = createSagaMiddleware() 
    const store = createStore(rootReducer, initialState, applyMiddleware(sagaMiddleware)); 
    let sagaTask = sagaMiddleware.run(function*() { 
    yield getSagas() 
    }) 
    if (module.hot) { 
    // Enable Webpack hot module replacement for reducers 
    module.hot.accept('../reducers',() => { 
     const nextRootReducer = require('../reducers/index'); 
     store.replaceReducer(nextRootReducer); 
    }); 
    module.hot.accept('../sagas',() => { 
     const getNewSagas = require('../sagas'); 
     sagaTask.cancel() 
     sagaTask.done.then(() => { 
     sagaTask = sagaMiddleware.run(function* replacedSaga (action) { 
      yield getNewSagas() 
     }) 
     }) 
    }) 
    } 

    return store; 
} 

Eine wichtige Sache ist die getSagas() Funktion zu bemerken. Es gibt ein Array von frisch erstellten Generatorobjekt von Sagas zurück, Sie können kein bereits erstelltes Objekt in dem Array von einigen bereits laufenden Sagas haben. Wenn Sie dieses Array nur in einem Modul bauen, können Sie direkt ein konstantes Array verwenden, aber wenn Sie es bauen Sagas aus verschiedenen Modulen zusammensetzen, müssen Sie sicher sein, sagas aus allen Modulen neu zu erstellen, also ist der bessere Weg das alle Module exportieren die Erstellungsfunktion, anstatt eine feste Saga oder ein Array von Sagas zu exportieren. Zum Beispiel könnte es eine Funktion wie folgt sein:

export default() => [ 
    takeEvery(SOME_ACTION, someActionSaga), 
    takeEvery(OTHER_ACTION, otherActionSaga), 
] 

Offensichtlich alle Sagas von Anfang an neu gestartet werden, und wenn Sie eine komplexe Sagas mit internen Zustand haben Sie den aktuellen Status verlieren.

Ein sehr ähnlicher Ansatz ist es, eine dynamische Saga anstelle von sagaMidleware.run() zu verwenden, es ist eine sehr ähnliche Lösung, aber Sie können Teilmengen der Sagas neu laden und sie auf verschiedene Arten behandeln. Für weitere Informationen siehe https://gist.github.com/mpolci/f44635dc761955730f8479b271151cf2

+1

Mein Problem gelöst. @kevin, Sie können dies als die richtige Antwort markieren, wenn es Ihr Problem gelöst hat. – wrick17

+0

@mpolci können Sie mehr über die Funktion getSagas erklären? Ich verstehe, dass Sie eine Reihe von Saga-Generator-Objekten erhalten möchten, aber wenn Sie mehrere Saga-Dateien haben, die Listener exportieren, würden Sie empfehlen, sie zu importieren und sie als Kette zu benennen? 'importiere getSaga1 aus '../ saga1'' importiere getSaga2 aus' ../ saga2' und dann in sagaTask 'getSaga1() getSaga2()' – mattgabor