Next.js v9.3版本引入了getServerSideProps,在定义服务端渲染这边页面上的props,getServerSideProps基本上取代了getInitialProps.
如今,仍然有些开发者对于使用哪个方法还是比较困惑,在这篇文章会通过各自举例来解释 getServerSideProps
和getInitialProps
工作原理,让我们开始吧!
getServerSideProps
和getInitialProps
内部工作原理
基本上来说,如果你要在编译阶段发出任何请求之前渲染页面,你应该使用getStaticProps
,该方法会使页面静态化进行渲染,也意味着后续不会被重复渲染直到下一次的编译。虽然该方法对于渲染速度及SEO有显著的提高,但它不适合经常改变的动态数据渲染方式。
如果你希望在请求时渲染页面,你可以使用getServerSideProps
方法,在客户端得到请求响应时渲染页面。该方法会对每个请求都是做页面渲染,虽然该方法使得服务端会对每个请求重新构建页面,从而降低整体的访问速度,然而该方法相比React在客户端渲染的普通方式有着较大的SEO优势。
关于语言和框架的升级,向后兼容性很重要,尽管老的模式或方法在后续的工程里不再使用,它们仍然被维护,以此保证不破坏遗留代码及边界情况。这就是
getInitialProps
的情况,它几乎和getServerSideProps
有着一样的用法行为。
getServerSideProps
和getInitialProps
那两者有什么不同点吗?
老的getInitialProps
方法和新的getServerSideProps
方法最大的区别点在于当用户点击链接访问不同区域时,如何在转换过程中使用该功能。
getInitialProps
这边转换在服务端初始化页发生,在客户端会再次执行,然而如果有涉及到数据库之类的逻辑,在客户端这边是不能直接访问的,这将会是发生问题。
【个人补充:这块就是确保同构的一致性,因为服务端没有DOM,所以不能处理事件等DOM相关行为,只能输出HTML String。因此相同的代码客户端需要再跑一次,把DOM的行为再加上,这样才能输出一张功能完整的页面供用户使用,这也是同构渲染的意义所在】
举个例子:
// Import a User model
import User from "../models/User"
function Page({ User }) {
return <div>Username: {User.username}</div>
}
Page.getInitialProps = async (ctx) => {
// Get user id
const User = await User.findOne(ctx.query.id)
// return props
return {
User
}
}
export default Page
在这个代码片段中,页面初始化可以通过User数据模型获取用户信息,然而在客户端当User数据模型不可使用的时候会操作失败。
作为其中一个解决方案,可以使用Next.js 自带的API服务进行端点接口提供,但这样比在服务端这边User数据模型直接访问数据库效率要低很多。
另外一个解决方案,可以使用getServerSideProps
方法,该方法会在服务端初始化页面执行,在客户端页面转换阶段,getServerSideProps
会在服务端生成一个API 调用接口,会再次运行处理逻辑并返回JSON格式作为结果。
通过做此更改,我们修复了getInitialProps
在切换时产生的问题。下面这个例子,可以访问数据库的同时,在初始页面的时候也不会报错
// Import a User model
import User from "../models/User"
function Page({ User }) {
return <div>Username: {User.username}</div>
}
export async function getServerSideProps(context) {
// Get user id
const User = await User.findOne(ctx.query.id)
return {
props: {User}, // will be passed to the page component as props
}
}
export default Page
那么什么情况下用哪个合适呢?
如果你通过Next.js创建了一个新的应用,那么你没有理由要使用遗留方法getServerSideProps
,因为getServerSideProps
和getStaticProps
方法会更加实用,语义更加明确。
在这篇文章,我们将阐明getServerSideProps
和getInitialProps
的区别,通过看一个例子来看看我们是如何解决getServerSideProps
解决getInitialProps
中的切换问题。
我希望你喜欢这篇文章,如果你有任何问题,请留言。要了解更多关于Next.js和其他元框架的信息,请务必查看这篇比较Next.js和Remix的文章。
LogRocket是一个使得Next.js应用完全可视化的工具。
调试Next应用程序可能很困难,特别是当用户遇到难以再现的问题时。如果您对监视和跟踪状态、自动显示JavaScript错误、跟踪缓慢的网络请求和组件加载时间感兴趣。
LogRocket就像一个网页和app的DVR录制机,录制Next.js应用程序上发生的一切,您不必猜测问题发生的原因,而是可以聚合和报告问题发生时应用程序的状态,LogRocket还监视应用程序的性能,报告客户端CPU负载、客户端内存使用情况等指标。
LogRocket Redux中间件包在用户会话中增加了一个额外的可见层。LogRocket记录Redux存储中的所有操作和状态。
原文:https://blog.logrocket.com/getinitialprops-vs-getserversideprops-nextjs/
补充总结:
在 Next.js 中,getInitialProps
和 getServerSideProps
是两个用于获取服务器端数据和传递给页面的 Prop(属性)的函数。它们之间有一些关键区别:
1. getInitialProps
getInitialProps
是一个较早的 Next.js 版本中引入的功能。它是一个异步函数,可以从服务器端和客户端请求数据。它适用于页面级别的组件,即 pages
目录中的文件。它的签名如下:
static async getInitialProps(ctx) {
// Fetch data
}
特点:
- 它在服务器端和客户端上都会执行
- 不能在非页面组件中使用
- 仅在初始化页面加载时运行,不在客户端的路由切换时运行
- 与 _app.js、_document.js 和 _error.js 中的
getInitialProps
结合使用时,需注意它们之间的关系和执行顺序
注意: 从 Next.js 9.3 版本开始,推荐使用 getStaticProps
和 getServerSideProps
替代 getInitialProps
。
2. getServerSideProps
getServerSideProps
是在 Next.js 9.3 及更高的版本中引入的新功能,用于服务器端的数据请求。与 getInitialProps
不同,getServerSideProps
只在服务器端运行。它的签名如下:
export async function getServerSideProps(ctx) {
// Fetch data
}
特点:
- 仅在服务器端执行,不在客户端执行
- 适用于需要每次展示最新数据的页面
- 在初始化页面加载时运行,并在客户端的路由切换时重新运行
- 不能在非页面组件中使用
总结:
- 当只在服务器端获取数据,且每次请求都需要获取新数据时,使用
getServerSideProps
。 - 当数据在服务器端和客户端都需要获取时,可以继续使用
getInitialProps
,但要注意 Next.js 推荐使用getStaticProps
和getServerSideProps
。
推荐使用 Next.js 的新功能 getStaticProps
和 getServerSideProps
,因为它们提供了更明确的服务器端数据请求方式,且可以更好地配合新的增量静态生成(ISR)功能。如果可以,尽量避免继续使用 getInitialProps
。