Использование Redux Saga в большом проекте - PullRequest
0 голосов
/ 11 февраля 2019

Я новичок вactjs и пытаюсь изучать саги.

Я создал корневой файл саги следующим образом.

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

Для каждого модуля я создал отдельный файл сагии поместил все эти связанные действия в этот файл.

Наконец, я взял все эти действия и объединил их в корневой саге.

Я предполагаю, когда проект станет большим и более сложными имеет много модулей, все наблюдатели будут добавлены так же, как и приведенный выше код

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

То есть корневая сага будет содержать довольно много наблюдателей - наблюдатели длялогин, панель инструментов, книги, учетные записи и т. д. *

Это правильный способ сделать это?

Ответы [ 3 ]

0 голосов
/ 12 февраля 2019

Цитируя Мартина ...

Я бы не назвал ни одно из решений "правильным".Просто поэкспериментируйте, что вам больше подходит.

Он прав, но вы хотите услышать об этом от других разработчиков: в моем текущем проекте файловая система организована, как показал Мартин, но корневая сага все еще элементарна

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

В моей корневой саге единственная разница в том, что я порождаю сагу аутентификации.Это делает подлинную сагу полностью независимой (как если бы я начал с sagaMiddleware.run(rootSaga);).

Затем все другие саги запускаются после действия LOGIN_SUCCESS и отменяются после действия LOGOUT_REQUEST.

Затем я ввел действие FREEZE только для целей отладки (у меня много сетевых опросов и журналов, которые могут утомлять меня при отладке).

В любом случае, по мере роста проекта я представлюорганизация, предложенная Мартином.

0 голосов
/ 22 мая 2019

Я использую InitSagas и вызываю его после инициализации Redux Store

//initSagas.js

import * as sagas from './sagas';

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

export default initSagas;

У меня есть index.js в папке Sagas, и я экспортирую из него все саги для использования в InitSagas.js

В моем getStore.js

//getSore.js
...

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

initSagas(sagaMiddleware);

return store;

Надеюсь, что это отвечает на ваш вопрос.

0 голосов
/ 12 февраля 2019

Организация саг очень похожа на организацию редукторов.Вы также, вероятно, начнете использовать combReducers в корневом редукторе с простым списком всех редукторов, и он может даже довольно хорошо масштабироваться.Длинные списки редукторов / саг обычно не являются источником особых проблем.

Однако, в конечном итоге, в обоих случаях вы можете захотеть ввести древовидную структуру.Например, если ваше приложение выглядит так:

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

Вы можете запустить свои саги следующим образом:

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

Я бы не назвал ни одно из решений "правильным".Просто поэкспериментируйте, что подходит вам лучше.

...