2016-05-10 16 views
10

私はReact & Reduxプロジェクトに取り組んでいました。このプロジェクトでは、webpack-devミドルウェアとホットミドルウェアを使用してホットリロードを行いました。Redux Sagaホットリロード

私はプロジェクトにRedux Sagaを追加し、reduxストアにsagaミドルウェアを追加しました。その場でstoreの変更をサポートしていません

プロバイダ>:私が佐賀コードを変更するたびに、ホットリロード意志が壊れ、エラーメッセージが表示されているようです。 Redux 2.xおよびReact Redux 2.xに更新されたため、このエラーが発生する可能性は非常に高いです。移行手順については、https://github.com/reactjs/react-redux/releases/tag/v2.0.0を参照してください。

私は佐賀の発電機を使用し、それは時間依存的であることを理解しています。 Sagasでページをホットリロードすることは可能ですか?ホットリロード中にReduxリデューサがどのように置き換えられるかと同じように。

ありがとうございます!

+0

をご覧ください。https://github.com/yelouafi/redux-saga/issues/22#issuecomment-218522365 –

答えて

16

私はreduxとredux-saga(ただし反応しません)のプロジェクトに取り組んでいます。私はsagaMiddleware.run()を使ってサガのホットリロードを実装しましたが、あなたが提供したリンク(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; 
} 

注目すべき重要なことは、getSagas()機能です。新しく作成されたサガのジェネレータオブジェクトの配列を返します。すでに実行されているサガの配列から事前処理されたオブジェクトをいくつか持つことはできません。この配列 を1つのモジュールでしか作成できない場合は、定数配列を直接使用することができますが、 を異なるモジュールから作成する場合は、すべてのモジュールからsagas を再作成する必要があります。モジュールは、固定されたサガまたはサガの配列をエクスポートする代わりに、関数を作成してエクスポートします。 例えば、それは、このような機能をすることができます

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

もちろん全てサガは最初から再開され、あなたが内部状態を持つ複雑なサガ を持っている場合は、現在の状態を失います。

非常によく似たアプローチは、sagaMidleware.run()の代わりにダイナミックサガを使用することです。これは非常によく似たソリューションですが、サガのサブセットをリロードしてさまざまな方法で処理できます。詳細はhttps://gist.github.com/mpolci/f44635dc761955730f8479b271151cf2

+1

私の問題を解決しました。 @kevin、あなたが問題を解決した場合は、これを正しい答えとすることができます。 – wrick17

+0

@mpolci getSagas関数の詳細を説明できますか?私はあなたがサガジェネレータオブジェクトの配列を取得したいと思いますが、リスナーをエクスポートする複数のサガファイルがある場合は、それぞれをインポートしてチェーンとして呼び出すことをお勧めしますか? '../saga1'からgetSaga1をインポートし、 '../saga2'からgetSaga2をインポートし、次にsagaTaskの' getSaga1()getSaga2() 'でgetSaga1をインポートします。 – mattgabor