我们有一个项目,与nextjs,redux传奇,打字设置。SSR对我们的web应用程序非常重要,但我们在每个页面上也有很多相关的小部件。
这就是为什么我们的页面是以模块化的方式构建的,每个小部件(每个页面1-2个)加载它需要的数据。这些小工具现在与SEO相关。
我的问题是,API请求不是在服务器端发出的。现在,它只返回服务器上每个小部件的defaultState,并且只在客户端加载它们。
我搜索并找到了很多关于如何做到这一点的指令,但它们都依赖于nextjs会等待"getInitialProps“方法,直到它从服务器返回结果。因为生命周期方法只在"pages“文件夹中可用,所以对我不起作用。
另外,如果我阻塞了"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那样。只需等到没有打开的请求或承诺,然后呈现即可。有什么想法吗?
任何帮助或想法都深表感谢。
谢谢
发布于 2021-10-12 10:19:13
由于您是redux sage,在getServerSideProps中,请向saga发送启动信号。
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 } };} );
saga函数内幕:
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()方法将可迭代的Promise作为输入,并返回单个Promise,该Promise解析为输入Promise的结果数组。当所有输入的promise都已解析,或者输入iterable不包含promise时,将解析此返回的promise。它在任何输入promises或non-promises抛出错误时立即拒绝,并将使用第一个拒绝消息/错误进行拒绝。
https://stackoverflow.com/questions/55107357
复制相似问题