使用getInitialProps向Next.js组件提供数据的方法

74 阅读2分钟

如何使用getInitialProps向Next.js组件提供数据

当我谈到向Next.js添加动态内容时,我们在动态生成帖子页面时遇到了一个问题,因为该组件需要一些前期数据,当我们试图从JSON文件中获取数据时。

import { useRouter } from 'next/router'
import posts from '../../posts.json'

export default () => {
  const router = useRouter()

  const post = posts[router.query.id]

  return (
    <>
      <h1>{post.title}</h1>
      <p>{post.content}</p>
    </>
  )
}

我们得到了这个错误。

我们如何解决这个问题?我们又如何使SSR在动态路由中工作?

我们必须为组件提供道具,使用一个名为getInitialProps() 的特殊函数,该函数被附加到组件上。

要做到这一点,首先我们要为该组件命名。

const Post = () => {
  //...
}

export default Post

然后我们把这个函数添加到它上面。

const Post = () => {
  //...
}

Post.getInitialProps = () => {
  //...
}

export default Post

这个函数得到一个对象作为其参数,其中包含几个属性。特别是,我们现在感兴趣的是,我们得到query 对象,也就是我们之前用来获取帖子ID的那个对象。

因此,我们可以使用对象析构的语法来获得它。

Post.getInitialProps = ({ query }) => {
  //...
}

现在我们可以从这个函数中返回帖子。

Post.getInitialProps = ({ query }) => {
  return {
    post: posts[query.id]
  }
}

而且我们还可以删除useRouter 的导入,我们从传递给Post 组件的props 属性中获得帖子。

import posts from '../../posts.json'

const Post = props => {
  return (
    <div>
      <h1>{props.post.title}</h1>
      <p>{props.post.content}</p>
    </div>
  )
}

Post.getInitialProps = ({ query }) => {
  return {
    post: posts[query.id]
  }
}

export default Post

现在不会有错误了,SSR将按预期工作,你可以看到检查视图源。

getInitialProps 函数将在服务器端执行,但也会在客户端执行,当我们使用Link 组件导航到一个新的页面时,就像我们做的那样。

值得注意的是,getInitialProps ,在它收到的上下文对象中,除了query 对象外,还得到了这些其他的属性。

  • pathname:URL的path 部分
  • asPath - 在浏览器中显示的实际路径(包括查询)的字符串

在调用http://localhost:3000/blog/test 的情况下,这将分别导致。

  • /blog/[id]
  • /blog/test

而在服务器端渲染的情况下,它还会收到。

  • req:HTTP请求对象
  • res:HTTP响应对象
  • err: 一个错误对象

req 如果你做过任何Node.js的编码, ,你会很熟悉。res