2016-05-10 42 views
10

Bir React & Redux projesi üzerinde çalışıyordum. Proje, yeniden yüklemek için webpack-dev-middleware ve hot middleware'i kullanıyordu.Redux Saga hot reloading

Redux Saga'yı projeye ekledikten sonra yinele ara yazılımını redux deposuna ekledim. Anında store değiştirilmesini desteklemez

Sağlayıcı>: Ben destan kodlarını değiştirdiğinizde, sıcak yüklenmesi irade kırdı ve bir hata mesajı görüntüler gibi görünüyor. Redux 2.x ve React Redux 2.x ile güncellediğiniz için bu hatayı görmeniz muhtemeldir çünkü artık otomatik olarak yeniden sıcak redüktörleri yüklemiyor. Taşıma talimatları için bkz. https://github.com/reactjs/react-redux/releases/tag/v2.0.0.

Saga'nın jeneratörler kullandığını ve zamana bağlı olduğunu anlıyorum. Sayfayı Sagas ile tekrar yüklemek mümkün mü? tıpkı Redux redüktörlerinin, sıcak yeniden yükleme sırasında kendini nasıl değiştirdiği gibi.

Teşekkürler!

+0

Tartışma https://github.com/yelouafi/redux-saga/issues/22#issuecomment-218522365 –

cevap

16

Redux ve redux-saga (ancak tepki vermiyor) ile bir proje üzerinde çalışıyorum. SagaMiddleware.run() yöntemini kullanarak sagas'ın yeniden yüklenmesini uyguladım ancak modülün yeniden yüklenmesini sağladım ve sağladığınız bağlantıda belirtildiği gibi redüktörleri ve sagmaları değiştirmelisiniz (https://github.com/reactjs/react-redux/releases/tag/v2.0.0). fark

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; 
} 

önemli bir şey getSagas() işlevidir. Sagas'ın yeni oluşturulmuş bir jeneratör nesnesinin bir dizisini döndürür; zaten çalışan bazı sagaslardan dizide bazı önceden işlenmemiş nesneye sahip olamazsınız. Bu diziyi yalnızca bir modülde varsa, doğrudan bir sabit dizi kullanabilirsiniz, ancak farklı modüller sagas oluşturma sagas inşa ederseniz, tüm modüllerden sagas yeniden oluşturduğunuzdan emin olmalısınız, böylece daha iyi bir yoldur modüller, sabit bir destan veya sagas dizisi dışa aktarmak yerine işlev oluşturmayı dışa aktarır. Örneğin böyle bir işlev olabilir:

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

Açıkçası bütün destanları baştan yeniden başlatılır ve dahili devletle karmaşık sagalarını varsa mevcut durumunu kaybeder.

Çok benzer bir yaklaşım, sagaMidleware.run() numaralı çağrı yerine dinamik bir destan kullanmaktır, bu çok benzer bir çözümdür, ancak saganın alt kümelerini yeniden yükleyebilir ve bunları farklı şekillerde işleyebilirsiniz. Daha fazla bilgi için bkz. https://gist.github.com/mpolci/f44635dc761955730f8479b271151cf2

+1

Sorunumu çözdüm. Kevin, bu sorunu çözdüyse, doğru cevap olarak işaretleyebilirsiniz. – wrick17

+0

@mpolci getSagas işlevi hakkında daha fazla bilgi verebilir misiniz? Bir dizi destan üreteci nesnesi almak istediğinizi anlıyorum, ancak dinleyicileri dışa aktaran birden fazla destansı dosyanız varsa, her birini içe aktarmanızı ve bunları zincir olarak çağırmanızı önerir misiniz? "getSaga1" i "/ saga1" 'den import getSaga2' den '../saga2' 'ye ve sonra sagaTask' getSaga1 'den (getSaga2() 'ye – mattgabor