у нас есть проект с установкой nextjs, redux saga, typescript. SSR очень важен для нашего веб-приложения, но у нас также есть много соответствующих виджетов на каждой странице.
Вот почему наша страница структурирована по модульному принципу, где каждый виджет (1-2 на странице) загружает нужные ему данные. Эти виджеты сейчас актуальны из соображений SEO.
Моя проблема в том, что запросы API не выполняются на стороне сервера. Прямо сейчас он только возвращает состояние по умолчанию каждого виджета на сервере и загружает их только на клиенте.
Я искал и нашел много инструкций, как это сделать, но все они основаны на том факте, что nextjs ждет метод "getInitialProps", пока не вернет результат с сервера. Поскольку этот метод жизненного цикла доступен только в папке «страницы», он мне не подходит.
Кроме того, если я заблокирую компонент «getInitialProps», компонент никогда не будет отображаться.
Наши страницы структурированы следующим образом:
- pages/Home
- <HomeContainer ...> (fetches data for the main page)
- <HomeComponent >
- <Widget1Container ...> (fetches data)
- <Widget2Container ...> (fetches data)
Я хочу, чтобы сервер дождался всех предоставленных запросов, прежде чем вернуть страницу пользователю. Из-за сложной природы различных виджетов на странице невозможно создать «комбинированную» конечную точку, где мы получаем данные в папке «pages/Home».
Я знаю, что это не идеально, но как мы можем убедиться, что сервер действительно делает все 3 запроса (homecontainer, widget1container, widget2container) и ожидает там ответов, прежде чем вернуться? Я хотел бы, чтобы это было так, как это делает angular-universal. Просто подождите, пока не будет открытых запросов или обещаний, а затем просто визуализируйте. Есть идеи?
Любая помощь или идеи глубоко оценены.
Спасибо





так как вы являетесь редукционным мудрецом, в getServerSideProps отправьте сигнал запуска в сагу
export const getServerSideProps = wrapper.getServerSideProps(
async (context) => {
store.dispatch(
fetchWidgetsStart("add payload")
);
store.dispatch(END);
await (store as SagaStore).sagaTask.toPromise();
const state = store.getState();
// I am making up the reducer name
const widgetListState = state.widgetsList ? state.widgetList : null;
return { props: { productListState } };
} );
внутри функции саги:
export function* fetchWidgetsStart() {
yield takeLatest(
WidgetListActionTypes.WIDGET_LIST_START,
fetchWidgetssAsync
);
}
function* fetchWidgetsAsync(action: IFetchWidgetssStart) {
try {
const res: AxiosResponse<IWidget[] | []> = Promise.all([
yield axios.get(fetchWidget1),
yield axios.get(fetchWidget2),
yield axios.get(fetchWidget3)
])
yield put(fetchWidgetSuccess(res));
} catch (e: any) {
yield put(
fetchWidgetFailure(
e.response && e.response.data.detail
? e.response.data.detail
: e.message
)
);
}
}
Метод Promise.all() принимает итерацию промисов в качестве входных данных и возвращает один промис, который разрешается в массив результатов входных промисов. Это возвращенное обещание будет разрешено, когда все обещания ввода будут разрешены, или если итерация ввода не содержит обещаний. Он немедленно отклоняет любое из входных промисов, отклоняющих или не промисов, выдающих ошибку, и отклоняет это первое сообщение об отклонении / ошибку.