官网《Next.js —— 为页面获取数据》

本文介绍如何使用Next.js的getInitialProps函数从远程API获取数据,并在客户端和服务端进行渲染。通过实例演示了从TVMaze API获取蝙蝠侠电视节目信息的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

现在我们知道如何创建一个像样的Next.js应用了,并且也充分使用了Next.js路由API。

在实践中,我们通常要从远程数据源获取数据。Next.js具备标准的获取数据的API,那就是成为同步函数的'getInitialProps'.用这个函数,我们就能从远程获取数据,并且以属性的方式传递回页面。我们能同时在客户端和服务端写入这个函数,所以,自然而然可以在两端使用。在这节课中,通过使用"getInitialProps",我们要建立一个能够展示“蝙蝠侠”电视节目信息的应用,并以公共的TVmaze API为数据源。让我们开始吧!

安装

在这节课中,我们仅仅需要一个简单的Next.js应用来掩饰。去下载如下事例应用:

git clone https://github.com/zeit/next-learn-demo.git
cd next-learn-demo
cd 6-fetching-data

用如下代码运行

npm install
npm run dev

然后就可以通过 http://localhost:3000/ 来访问这个应用了。

 

获取蝙蝠侠电视节目

在我们的事例应用中,首页有一个博客列表。现在我们要显示一个蝙蝠侠电视列表,对硬编码取而代之的是我们要从远程服务端获取数据。

在这里我们用TVMaze API(http://www.tvmaze.com/api)来获取电视节目。它是一个能够搜索电视节目信息的API

首先我们要安装'isomorphic-unfetch',这是一个可以获取数据的库,它是对浏览器的fetch API的简单实现,但却可以同时运行在客户端和服务端环境。

npm install --save isomorphic-unfetch

然后用如下内容来代替'pages/index.js'

import Layout from '../components/MyLayout.js';
import Link from 'next/link';
import fetch from 'isomorphic-unfetch';

const Index = props => (
  <Layout>
    <h1>Batman TV Shows</h1>
    <ul>
      {props.shows.map(show => (
        <li key={show.id}>
          <Link as={`/p/${show.id}`} href={`/post?id=${show.id}`}>
            <a>{show.name}</a>
          </Link>
        </li>
      ))}
    </ul>
  </Layout>
);

Index.getInitialProps = async function() {
  const res = await fetch('https://api.tvmaze.com/search/shows?q=batman');
  const data = await res.json();

  console.log(`Show data fetched. Count: ${data.length}`);

  return {
    shows: data.map(entry => entry.show)
  };
};

export default Index;
除了“Index.getInitialProps”以上的代码都对你是如此熟悉,正如下面所示
Index.getInitialProps = async function() {
  const res = await fetch('https://api.tvmaze.com/search/shows?q=batman');
  const data = await res.json();

  console.log(`Show data fetched. Count: ${data.length}`);

  return {
    shows: data.map(entry => entry.show)
  };
};

这是一个静态同步函数,你可以将它添加到你应用中的任何页面。使用它,我们就可以获取数据并且把数据作为属性传递到页面中了。

如你所见,我们拿到了蝙蝠侠电视节目列表并且将其以"shows"这个属性传递到页面中。

正如上面的"getInitialProps"这个函数,它在控制台打印出一些获取的数据,之后看看服务端控制台和浏览器的控制台,并且刷新页面。在刷新后你在哪里看到了数据的数量?

答案是:在服务端控制台

 

只在服务端

之所以只在服务端打印出了数据,是因为我们是在服务端渲染了页面,既然在服务端拿到了数据就没有理由再在客户端获取一遍。

 

实现Post页面

现在让我们去实现post页面,这个页面是用来展现电视节目详情的地方。首选,打开"server.js",然后用如下内容改变"/p/:id"这个路由:

server.get('/p/:id', (req, res) => {
  const actualPage = '/post';
  const queryParams = { id: req.params.id };
  app.render(req, res, actualPage, queryParams);
});

然后重启你的项目,运行上面的代码

现在让我们替换"pages/post.js"这个文件代码,内容如下:

import Layout from '../components/MyLayout.js';
import fetch from 'isomorphic-unfetch';

const Post = props => (
  <Layout>
    <h1>{props.show.name}</h1>
    <p>{props.show.summary.replace(/<[/]?p>/g, '')}</p>
    <img src={props.show.image.medium} />
  </Layout>
);

Post.getInitialProps = async function(context) {
  const { id } = context.query;
  const res = await fetch(`https://api.tvmaze.com/shows/${id}`);
  const show = await res.json();

  console.log(`Fetched show: ${show.name}`);

  return { show };
};

export default Post;

看一下"getInitialProps"这个页面的函数

Post.getInitialProps = async function(context) {
  const { id } = context.query;
  const res = await fetch(`https://api.tvmaze.com/shows/${id}`);
  const show = await res.json();

  console.log(`Fetched show: ${show.name}`);

  return { show };
};

在这个函数里的第一个参数是context对象,它有一个query字段用来获取获取数据。在我们的例子中,我们选择ID作为查询参数并且从TVMaze中获取数据。

在 " getInitialProps " 这个函数中,我们添加了"console.log"来打印标题。现在我们要看看打印在哪里显示。

同时打开服务端的控制台和客户端控制台。然后访问首页"http://localhost:3000" 并且店家第一个“蝙蝠侠节目”的标题。你会在哪里看到"console.log"的信息呢?

答案是:在浏览器控制台。

 

在客户端获取数据

我们看到在客户端显示了控制台信息,这是因为我们是依赖于客户端才导航到post页面的。当我们点击<Link>时,页面转换会发生在浏览器里,而不是向服务端请求。

如果你直接访问post页面(比如:http://localhost:3000/p/975),你就会发现信息是打印在服务端,而不是客户端!

 

最后

现在您已经知晓了使Next.js趋于完整的最重要的特性之一:获取数据和服务端渲染。通过学习"getInitialProps",我们足够可以应付大部分情况了。当然你也可以参考Next.js的文档来查询获取数据“data fetching”的更多信息!

【原文链接:https://nextjs.org/learn/basics/fetching-data-for-pages

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值