У меня проблемы с ожиданием завершения "одного потока действий" от начала до конца. Приложение работает как обычно в клиенте, но при работе на стороне сервера оно не заканчивается до конца.
Для пояснения, я правильно использую и "next-redux-wrapper", и "next-redux-saga", так как могу добиться отложенного рендеринга, когда использую более простой поток с sagas.
Я думаю, что ошибка в основном в том, что я вообще понимаю (или нет) эффекты саги.
Часть кода опущена для краткости.
api.saga.js
const makeRequest = ({ body, url, method }) =>
axios({ method, url: url, data: body });
export function* requestWatcher(action) {
const { feature } = action.meta;
try {
const { data: response } = yield call(makeRequest, action.meta);
yield put(apiSuccess({ response, feature }));
} catch (error) {
yield put(apiError({ error: error, feature }));
}
}
export default function* apiSaga() {
yield takeEvery(action => action.type.includes(API_REQUEST), requestWatcher);
}
smallBusiness.saga.js
function* watchApiSuccess(action) {
yield put(
setPositions({ positions: action.payload.positions })
);
yield put(setLoader({ isLoading: false, feature: SMALL_BUSINESS }));
}
function* watchApiError() {
yield put(setLoader({ isLoading: false, feature: SMALL_BUSINESS }));
}
function* watchFetchPositions() {
yield put(
apiRequest({
body: null,
method: 'GET',
url: SMALL_BUSINESS_URL,
feature: SMALL_BUSINESS
})
);
yield put(setLoader({ isLoading: true, feature: SMALL_BUSINESS }));
}
export default function* smallBusinessSaga() {
yield all([
takeLatest(`${SMALL_BUSINESS} ${API_SUCCESS}`, watchApiSuccess),
takeLatest(`${SMALL_BUSINESS} ${API_ERROR}`, watchApiError),
takeLatest(FETCH_POSITIONS, watchFetchPositions)
]);
}
rootSaga.js
export default function* rootSaga() {
yield all([call(smallBusinessSaga), call(apiSaga)]);
}
configureStore.js
store.sagaTask = sagaMiddleware.run(rootSaga);
На стороне клиента вызывается функция «watchApiSuccess», а на стороне сервера - нет. Каждая функция генератора называется серверной, за исключением уже упомянутой.
Когда я упросту поток с помощью кода, приведенного ниже, приложение выполнит предварительный рендеринг на стороне сервера.
function* watchPrefetchPositions() {
const meta = {
body: null,
method: 'GET',
url: SMALL_BUSINESS_URL,
feature: SMALL_BUSINESS
};
const { data: response } = yield call(makeRequest, meta);
yield put(setPositions({ positions: response.positions }));
}
export default function* smallBusinessSaga() {
yield all([
...
takeLatest(PRE_FETCH_POSITIONS, watchPrefetchPositions)
]);
}
Главная проблема, с которой я не могу иметь сложные потоки, заключается в том, что саги не смогут выполнять такие вещи, как нормализация и многое другое.