3
votes

Utiliser Redux Saga dans un grand projet

Je suis nouveau dans reactjs et j'essaie d'apprendre la saga.

J'ai construit un fichier de saga racine comme suit.

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

Pour chaque module, j'ai créé un Séparez le fichier de la saga et mettez toutes ces actions liées dans ce fichier.

Enfin, j'ai pris toutes ces actions et les ai combinées dans la saga racine.

Je suppose, quand le projet devient grand et plus complexe et a beaucoup de modules, tous les observateurs seront ajoutés de la même manière que le code ci-dessus

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()
   ]);
}

Autrement dit, la saga racine contiendra beaucoup d'observateurs - des observateurs pour la connexion, le tableau de bord, les livres, les comptes, etc.

Est-ce la bonne façon de procéder?


1 commentaires

Nous exportons simplement les tableaux avec les sagas de chaque module, puis les répartissons dans le tableau passé à all dans rootSaga


3 Réponses :


4
votes

Organiser des sagas est un peu comme organiser des réducteurs. Vous commencerez probablement également à utiliser combineReducers dans le réducteur de racine avec une liste plate de tous les réducteurs et il peut même évoluer assez bien. Les longues listes de réducteurs / sagas ne sont généralement pas la source de beaucoup de problèmes.

Cependant, dans les deux cas, vous voudrez peut-être introduire une structure arborescente. Par exemple, si votre application ressemble à ceci:

// 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)
}

Vous pourriez exécuter vos sagas de cette façon:

+-- 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

Je ne le ferais pas ' t appeler l'une ou l'autre solution la "correcte". Essayez simplement ce qui vous convient le mieux.


0 commentaires

0
votes

Citant Martin ...

Je n'appellerais aucune des deux solutions la "bonne". Essayez simplement ce qui vous convient le mieux.

Il a raison mais vous voulez entendre d'autres développeurs donc: dans mon projet actuel, le système de fichiers est organisé comme l'a montré Martin mais la saga racine est toujours élémentaire

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

Dans ma saga racine, la seule différence est que je crée la saga d'authentification. Cela rend la saga auth complètement indépendante (comme si j'aurais commencé avec sagaMiddleware.run(rootSaga);).

Ensuite, toutes les autres sagas sont lancées après un L'action LOGIN_SUCCESS et annulée après une action LOGOUT_REQUEST .

J'ai ensuite introduit l'action FREEZE juste à des fins de débogage (j'ai beaucoup de sondages réseau et journalisation qui peuvent m'ennuyer lors du débogage).

Quoi qu'il en soit, au fur et à mesure que le projet grandit, je présenterai l'organisation proposée par Martin.


0 commentaires

0
votes

J'utilise InitSagas et l'appelle après avoir initialisé le Redux Store

//getSore.js
...

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

initSagas(sagaMiddleware);

return store;

J'ai un index.js dans mon dossier Sagas et j'exporte toutes les sagas à partir de celui-ci pour les consommer dans InitSagas.js

Dans mon getStore.js

//initSagas.js

import * as sagas from './sagas';

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

export default initSagas;

J'espère que cela répond à votre question.

p>


0 commentaires