Redux Sagas 未使用 redux persist 和 connected-react-router 进入

Posted

技术标签:

【中文标题】Redux Sagas 未使用 redux persist 和 connected-react-router 进入【英文标题】:Redux Sagas not entered with redux persist and connected-react-router 【发布时间】:2019-07-12 16:15:19 【问题描述】:

我有一个使用 redux、connected-react-router、redux saga 和 redux persist 以及带有 react-hot-loader 和 webpack 的 HMR 的 react Web 应用程序。在对大多数包进行重大更新后,我注意到没有输入/执行 saga。

相关包的当前版本为: “react”:“^16.7.0”,“react-redux”:“^6.0.0”,“redux”:“^4.0.1”,“redux-persist”:“5.6.12”,“redux-传奇”:“^1.0.1”,“react-hot-loader”:“^4.6.5”,“connected-react-router”:“^6.2.2”,“webpack”:“^4.29.3” .

我已尝试将 HMR 实施从 v4 恢复到更低版本,但我相信这正在发挥作用。我还认为它可能是连接的反应路由器的实现,但我现在对此也很有信心(但我会同时展示两者以供参考)。我猜这与我的 redux 商店配置有关,但我想如果我知道我不会寻求帮助。

index.js 文件(应用程序入口点)

import React from 'react';
import ReactDOM from 'react-dom';
import  PersistGate  from 'redux-persist/integration/react';
import  Provider  from 'react-redux';
import App from './components/App';
import store,  persistor  from './store/config';

const render = (Component) => 
  ReactDOM.render(
    <Provider store=store>
      <PersistGate persistor=persistor>
        <Component />
      </PersistGate>
    </Provider>,
    document.getElementById('app'),
  );
;

render(App);

根减速器:

import  combineReducers  from 'redux';
import  connectRouter  from 'connected-react-router';
import  stateKeys  from '../types';
import authReducer from './auth/authReducer';

export default history => combineReducers(
  [stateKeys.ROUTER]: connectRouter(history),
  [stateKeys.AUTH]: authReducer,
);

根传奇:

import watchAuthentication from './auth/sagas';

const root = function* rootSaga() 
  yield [
    watchAuthentication(),
  ];
;

export default root;

App.js(仅相关位):

import  hot  from 'react-hot-loader';
class App extends React.Component 
...

export default hot(module)(connect(mapStateToProps, mapDispatchToProps)(App));

存储配置:

import 
  applyMiddleware,
  compose,
  createStore,
 from 'redux';
import createSagaMiddleware from 'redux-saga';
import  createMigrate, persistStore, persistReducer  from 'redux- 
persist';
import storage from 'redux-persist/lib/storage';
import reduxImmutableStateInvariant from 'redux-immutable-state- 
invariant';
import  createBrowserHistory  from 'history';
import  routerMiddleware  from 'connected-react-router';
import  manifest  from '../manifest';
import rootReducer from '../rootReducer';
import sagas from '../rootSaga';
import  stateKeys  from '../../types';


// persistence config
const persistConfig = 
  key: 'root',
  whitelist: [
    stateKeys.MANIFEST,
    stateKeys.VERSION,
  ],
  storage,
  migrate: createMigrate(manifest),
;

// Create and export the history object
export const history = createBrowserHistory();


// Middlewares setup
const reactRouterMiddleware = routerMiddleware(history);
const sagaMiddleware = createSagaMiddleware();

const middlewares = [];

// during development: enforce immutability and provide extended support for redux debugging tools.
let composeEnhancers = compose;

if (process.env.NODE_ENV === 'development') 
  middlewares.push(reduxImmutableStateInvariant());
  composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || 
composeEnhancers; // eslint-disable-line no-underscore-dangle, max-len


middlewares.push(sagaMiddleware, reactRouterMiddleware);

// create the redux store
const initialState = undefined;

const store = createStore(
  persistReducer(persistConfig, rootReducer(history)),
  initialState,
  composeEnhancers(applyMiddleware(...middlewares)),
);

// hot module replacement config
if (process.env.NODE_ENV === 'development' && module.hot) 
  module.hot.accept('../rootReducer', () => 
    const nextReducer = require('../rootReducer').default; // eslint-disable-line global-require
    store.replaceReducer(persistReducer(persistConfig, 
nextReducer(history)));
  );


// run the saga middleware
sagaMiddleware.run(sagas);

export const persistor = persistStore(store);
export default store;

验证传奇:

import 
  call,
  take,
  takeLatest,
 from 'redux-saga/effects';
import * as actions from '../authActions';
import config from '../../../mockData/mock-config';

// Use mocked auth flow if mocked authentication is enabled in mock- 
   config.js.
   // If mocked auth is used, you can change the user object in the 
    mock-config.js
    const  authenticateFlow, signOutFlow  = (config.enabled && 
    config.mockAuthentication) ? require('./mockedAuthFlow') : 
    require('./authFlow');

console.log('Outside watchAuthentication: sagas are not 
running...why?');


export default function* watchAuthentication() 
  while(true)  // eslint-disable-line
    try 
      console.log('Inside watchAuthentication... we never get here, 
why? ');

      const loginAction = yield takeLatest(`$actions.login`);
      yield call(authenticateFlow, loginAction);

      const signOutAction = yield take(`$actions.loginSignOut`);

      yield call(signOutFlow, signOutAction);
     catch (e) 
      console.warn('login flow failed');
    
  

我希望 watchAuthentication 中的控制台日志能够运行,但它永远不会运行。我相信问题出在商店配置上,但此时我正在猜测并抓住稻草,因为我不知道在哪里看。我知道这是一个复杂的问题,我感谢任何人可以提供的任何帮助。提前致谢!!

【问题讨论】:

我注意到从 redux-saga "redux-saga": "^0.15.6" 到 "redux-saga": "^1.0.1" 导致了重大变化,但不知道为什么。如果其他人也遇到此问题,我将继续调查。 你有没有弄清楚是什么导致你的手表停止工作? 我做了,我会添加一个答案 【参考方案1】:

redux saga 升级的问题在于 root saga。 我的解决方案是使用 yield all 如下:

import  all  from 'redux-saga/effects';
import watchAuthentication from './auth/sagas';

const root = function* rootSaga() 
  yield all([
    watchAuthentication(),
  ]);
;

export default root;

希望这对某人有所帮助。

【讨论】:

以上是关于Redux Sagas 未使用 redux persist 和 connected-react-router 进入的主要内容,如果未能解决你的问题,请参考以下文章

如何设置 redux-sagas 和文件结构?

将firebase与redux-sagas连接的正确方法是啥?

将观察者传递给 redux-sagas

如何将 redux-sagas 与 react-hooks 一起使用

连接firebase和redux-sagas的正确方法是什么?

react / redux / sagas - 如何基于现有商店数据链接动作?