- 使用
getInitialProps
:
getInitialProps
是 Next.js 特有的静态方法,在服务器端和客户端都会执行。
- 当页面路由变化(
id
参数变化)时,Next.js 会重新调用这个方法。
- 代码示例:
import React from'react';
const Post = ({ post }) => {
return (
<div>
<h1>{post.title}</h1>
<p>{post.content}</p>
</div>
);
};
Post.getInitialProps = async ({ query }) => {
const response = await fetch(`https://api.example.com/posts/${query.id}`);
const post = await response.json();
return { post };
};
export default Post;
- 优点:在服务器端渲染时就可以获取数据,有利于 SEO。数据获取在组件实例化之前,减少了不必要的客户端请求。
- 缺点:如果页面已经在客户端渲染,并且
id
参数变化,getInitialProps
会再次在客户端执行,可能会有重复请求。
- 结合
componentDidMount
和 useEffect
(针对客户端优化):
- 在客户端,
componentDidMount
(类组件)或 useEffect
(函数组件)可以用来监听 id
参数的变化。
- 对于函数组件,可以使用
useEffect
结合 useState
来管理数据。
- 代码示例:
import React, { useState, useEffect } from'react';
const Post = ({ initialId }) => {
const [post, setPost] = useState(null);
const [currentId, setCurrentId] = useState(initialId);
useEffect(() => {
const fetchData = async () => {
const response = await fetch(`https://api.example.com/posts/${currentId}`);
const data = await response.json();
setPost(data);
};
fetchData();
}, [currentId]);
useEffect(() => {
setCurrentId(initialId);
}, [initialId]);
return (
<div>
{post && (
<div>
<h1>{post.title}</h1>
<p>{post.content}</p>
</div>
)}
</div>
);
};
Post.getInitialProps = async ({ query }) => {
return { initialId: query.id };
};
export default Post;
- 优点:通过
useEffect
的依赖数组,可以精准控制数据获取时机,避免不必要的重复请求。在客户端可以更灵活地处理参数变化后的请求。
- 缺点:相比纯
getInitialProps
,在服务器端渲染时可能会有一些额外的逻辑处理。
- 缓存机制:
- 为了进一步避免重复请求,可以实现一个简单的缓存机制。
- 例如,使用一个全局变量来存储已经获取的数据。
- 代码示例(修改
getInitialProps
部分):
let cache = {};
Post.getInitialProps = async ({ query }) => {
if (!cache[query.id]) {
const response = await fetch(`https://api.example.com/posts/${query.id}`);
const post = await response.json();
cache[query.id] = post;
}
return { post: cache[query.id] };
};
- 优点:有效减少重复请求,提高数据获取效率。
- 缺点:需要注意缓存的清理和更新,防止数据过时。