我getServerSideProps 用来获取初始文章数据,如下所示:
export const getServerSideProps = async () => {\n const url =\n "https://conduit.productionready.io/api/articles?limit=10&offset=0";\n const res = await fetch(url);\n const resJson = await res.json();\n\n return {\n props: {\n data: resJson.articles\n }\n };\n};\nRun Code Online (Sandbox Code Playgroud)\n我需要在页面更改时更新文章\xef\xbc\x8cso我有以下代码:
\nexport default function IndexPage(props) {\n const { data } = props;\n const [articles, setArticles] = useState(data);\n const [page, setPage] = useState(0);\n\n useEffect(() => {\n const fetchData = async (page) => {\n const url = `https://conduit.productionready.io/api/articles?limit=10&offset=${page}`;\n const res = await fetch(url);\n const resJson = await res.json();\n setArticles(resJson.articles);\n };\n\n fetchData(page);\n }, [page]);\n\n //....\n}\nRun Code Online (Sandbox Code Playgroud)\n那么问题来了:
\ngetServerSideProps 在服务器端运行并获取文章。但在客户端, fetchData也会useEffects再次运行来获取相同的文章,这是多余的并且有点重复。IndexPage相同的文章数据时,也会有两个请求:一个请求发送到getServerSideProps服务器端运行,另一个请求发送给服务器端 fetchData。同样,对相同数据的冗余请求。完整的演示在这里
\n我认为这并不是一个不寻常的情况。我进行了很多搜索,但不幸的是,我还没有找到任何合适的解决方案。有谁遇到过同样的情况或知道处理它的最佳实践吗?
\n也许答案与某人相关。
在你的情况下,一切正常,因为useEffect页面中间的组件将始终被播放,因为这是React的通常逻辑,它看到该IndexPage组件是新的并且按照React中通常的安装规则运行您声明的所有效果,在您的情况下,有必要将获取函数移至单击事件处理程序:
const fetchData = async (page) => {
const url = `https://conduit.productionready.io/api/articles?limit=10&offset=${page}`;
const res = await fetch(url);
return await res.json();
};
const handleClick = async (page) => {
const nextPage = page >= 0 ? page : 0;
const data = await fetchData(nextPage);
setPage(nextPage);
setArticles(data.articles);
};
return (
...
<button onClick={() => handleClick(page - 1)}>Previous Page</button>
<button onClick={() => handleClick(page + 1)}>Next Page</button>
...
)
Run Code Online (Sandbox Code Playgroud)
完整的示例链接在这里。
但也许遇到这个问题的人正在寻找nextjs执行所有操作useEffect并且在这种情况下不作为 SPA 工作这一事实的答案,您可以通过以下链接了解如何设计布局,以便将nextjs其包装为 SPA这里。或者根据我关于如何使用 SPA 布局进行设计的故事,请参见此处的next18-next链接。