在大型项目中使用Redux Saga

时间:2019-02-11 09:40:46

标签: reactjs redux-saga

我是ReactJS的新手,正在尝试学习传奇。

我已经建立了如下的根传奇文件。

import { all } from 'redux-saga/effects';

import { watchBookFetchRequest } from './bookSaga'
import { watchAuthRequest, watchIsLoggedInRequest, watchLogoutRequest } from './authSaga'

export default function* rootSaga() {
   yield all([
    watchAuthRequest(),
    watchBookFetchRequest(),
    watchIsLoggedInRequest(),
    watchLogoutRequest()
   ]);
}

对于每个模块,我创建了一个单独的saga文件,并将所有这些相关操作放入该文件中。

最后,我采取了所有这些措施,并将其合并为根传奇。

  

我认为,当项目变得越来越大,越来越复杂并且有很多东西时   的模块,所有观察者将以与   以上代码

export default function* rootSaga() {
   yield all([
    watchRequest1(),
    watchRequest2()
    .
    .
    .
    watchRequestn()
   ]);
}

也就是说,根源传奇将包含很多观察者-登录,仪表板,帐簿,帐户等的观察者。

这是这样做的正确方法吗?

3 个答案:

答案 0 :(得分:2)

组织除草剂很像组织还原剂。您可能还可能会在根化约简的所有reducer列表中开始使用CombineReducers,它甚至可以很好地扩展。减速器/传奇的一长串通常不会带来很多问题。

但是,在两种情况下最终都可能要引入树结构。例如,如果您的应用程序如下所示:

+-- services/
|   +-- live-updates
|   |   +-- live-updates-saga.js
|   +-- local-storage
|   |   +-- local-storage-saga.js
|   +-- services-saga.js
+-- sections/
|   +-- home
|   |   +-- home-saga.js
|   +-- contacts
|   |   +-- contacts-saga.js
|   +-- sections-saga.js
+-- root-saga.js

您可以这样运行sagas:

// root-saga.js
function* rootSaga () {
    yield all([
        fork(servicesSaga),
        fork(sectionsSaga),
    ])
}

// services-saga.js
function* servicesSaga () {
    yield all([
        fork(liveUpdatesSaga),
        fork(localStorageSaga),
    ])
}

// sections-saga.js
function* sectionsSaga () {
    yield all([
        fork(homeSaga),
        fork(conactsSaga),
    ])
}

// live-updates/local-storage/home/contacts-saga.js
function* liveUpdatesSaga () {
    yield takeEvery(XYZ, xyzSaga)
}

我不会将任何一种解决方案称为“正确”的解决方案。只是尝试一下什么套件可以更好。

答案 1 :(得分:0)

引用马丁...

  

我不会将任何一种解决方案称为“正确”的解决方案。只是尝试一下什么套件可以更好。

他是对的,但是您想听听其他开发人员的话:在我当前的项目中,文件系统按照Martin的显示进行组织,但根源仍然是基本的故事

export function* rootSaga() {
  yield spawn(authSaga);

  while (true) {
    yield take(LOGIN_SUCCESS);
    // the indipendent sagas are all started after the LOGIN_SUCCESS action

    const tasks = [
      yield fork(pollBtcValueSaga),
      yield fork(getConfigSaga),
      yield fork(setTimeSaga),
      // and so on...
    ];
    console.log("sagas started");

    yield take([LOGOUT_REQUEST, FREEZE]);

    // the indipendent sagas are all stopped after the LOGOUT_REQUEST (or FREEZE) action
    for (let i = 0, n = tasks.length; i < n; i++) {
      yield cancel(tasks[i]);
    }
    console.log("️sagas stopped");
  }
}

在我的根源传奇中,唯一的区别是我生成了身份验证传奇。这使auth传奇完全独立(例如,如果我本来以sagaMiddleware.run(rootSaga);开始的话)。

然后在进行LOGIN_SUCCESS动作后开始所有其他sagas,并在进行LOGOUT_REQUEST后取消。

然后我仅出于调试目的而引入了FREEZE操作(我在调试时有很多网络民意调查和日志记录,这些都可能使我感到厌烦)。

无论如何,随着项目的发展,我将介绍马丁提出的组织。

答案 2 :(得分:0)

我使用InitSagas并在初始化Redux Store后调用它

//initSagas.js

import * as sagas from './sagas';

  const initSagas = (sagaMiddleware) => {
    Object.values(sagas).forEach(sagaMiddleware.run.bind(sagaMiddleware));
  };

export default initSagas;

我在Sagas文件夹中有一个index.js,并从中导出所有的Sagas以便在InitSagas.js中使用

在我的getStore.js

//getSore.js
...

const store = createStore(rootReducer, composeEnhancers(...enhancers));

initSagas(sagaMiddleware);

return store;

希望这能回答您的问题。