gpt4 book ai didi

javascript - Next.JS 静态站点生成和客户端 Apollo 获取

转载 作者:行者123 更新时间:2023-12-03 20:45:49 27 4
gpt4 key购买 nike

我正在利用 Next.JS SSG 来提高我网站的加载速度。关键是我需要在客户端获取一些数据,因为它属于登录用户。
假设我们有一个类似 YouTube 的网站,所以我们会有 Video page和一个侧边栏组件,这将是 VideoRelated :
我会生成 Video page静态,通过使用 VideoQuerygetStaticProps .它还将获取(客户端)登录用户的完成状态,因此它类似于:

export const VideoRelatedList = ({ videoId, relatedVideos }) => {
const { data } = useViewerVideoStatusQuery({ variables: { videoId } });
const relatedVideosViewerStatus = data?.videos;

const videos = React.useMemo(() => {
if (!relatedVideosViewerStatus) return relatedVideos;

return relatedVideos.map((relatedVideo, index) => {
const viewerHasCompleted = relatedVideosViewerStatus[index]?.id === relatedVideo.id && relatedVideosViewerStatus[index]?.viewerHasCompleted;
return { ...relatedVideo, viewerHasCompleted };
});
}, [relatedVideosViewerStatus, relatedVideos]);

return (
<ol>
{videos.map(({ id, name, viewerHasCompleted }, index) => (
<li key={id}>
{name} - {viewerHasCompleted && 'COMPLETED!'}
</li>
))}
</ol>
);
};
结合这两种数据的最佳方法是什么?
目前,我正在做的是通过使用 React.memo 将两者结合起来。但我不确定这是否是最佳实践,或者是否有更好的方法来实现我想要的。

最佳答案

tl;dr 这似乎是一个很好的方法,你可能不需要 useMemo
Next.js 文档有 a very brief blurb在客户端数据获取上。它看起来,本质上,就像你在做什么,除了他们宣传他们的 swr用于通用数据获取的库。
由于您使用的是 GraphQL 和 Apollo,因此我将假设 useViewerVideoStatusQuery扩展 useQuery hook from @apollo/client .
你提到:

Currently, what I'm doing is combining both by using React.memo but I'm not sure if this is a best practice or if there is a better way of achieving what I want.


请耐心等待,我将尝试确认我对您的用例的理解。如果我没看错,它看起来像 VideoRelatedList组件大部分可以是完全静态的,看起来这就是你所做的 - 如果没有加载额外的数据,它只是使用通过 SSG 构建的 props 传递的数据。那很好,应该给你最快的 First Contentful Paint (FCP) & Largest Contentful Paint (LCP) .
如果没有额外的数据,组件看起来就像:
export const VideoRelatedList = ({ videoId, relatedVideos }) => {
return (
<ol>
{relatedVideos.map(({ id, name, viewerHasCompleted }, index) => (
<li key={id}>
{name} - {viewerHasCompleted && 'COMPLETED!'}
</li>
))}
</ol>
);
};
现在你 另外想要合并用户数据,以提供告诉用户哪些视频是完整的功能。您是通过在页面最初使用 Apollo 呈现后获取数据来实现的。
我要做的主要改变(除非 relatedVideos 数组很大或者我错过了一些昂贵的操作)是删除 useMemo因为考虑到 performance optimizations aren't free,它可能不会在这里节省大量成本.
您也可以实现 loadingerror来自 useQuery 的属性钩。该组件可能类似于:
export const VideoRelatedList = ({ videoId, relatedVideos }) => {
const { data, loading, error } = useViewerVideoStatusQuery({ variables: { videoId } });

if (loading) {
<ol>
{relatedVideos.map(({ id, name, viewerHasCompleted }, index) => (
<li key={id}>
{name} - ...checking status...
</li>
))}
</ol>
}

if (error || !data.videos) {
return (
<ol>
{videos.map(({ id, name, viewerHasCompleted }, index) => (
<li key={id}>
{name}
</li>
))}
</ol>
);
}

const videos = relatedVideos.map((relatedVideo, index) => {
const viewerHasCompleted = relatedVideosViewerStatus[index]?.id === relatedVideo.id && relatedVideosViewerStatus[index]?.viewerHasCompleted;
return { ...relatedVideo, viewerHasCompleted };
});

return (
<ol>
{videos.map(({ id, name, viewerHasCompleted }, index) => (
<li key={id}>
{name} - {viewerHasCompleted && 'COMPLETED!'}
</li>
))}
</ol>
);
};
再说一次,这与你所做的没有很大的不同,除了没有 useMemo和一些重新排列。希望从另一个 Angular 了解该主题至少会有所帮助。
我发现有关该主题的一些引用资料:
  • Advice here regarding the structure to use with useQuery
  • A more thorough outline of GraphQL/Apollo implementations specifically.
  • 关于javascript - Next.JS 静态站点生成和客户端 Apollo 获取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65714664/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com