现在我们知道如何在Next.js 应用中创建多个页面。为了创建一个页面,我们必须要在硬盘中创建一个真实的文件。
然而,在实际的项目中,我们需要创建动态页面去显示动态内容。对于Next.js 我们有很多途径来实现。
我们首先用“查询字符”来创建一个动态页面,我们要创建一个简单的“博客”应用,这个页面在首页有很多帖子列表。(如图)
当你点击某个帖子的标题,你就能够在这个页面看到特定的帖子的内容。
让我们创建这个应用吧!
安装
首先,我们需要一个简单的Next.js 应用,试着去下载如下的应用例子:
git clone https://github.com/arunoda/learnnextjs-demo.git
cd learnnextjs-demo
git checkout using-shared-components
你可以用如下的代码运行它:
npm install
npm run dev
现在,你可以通过http://localhost:3000来访问这个应用
增加一个帖子列表
首先,在首页增加帖子的标题列表,添加如下内容到‘pages/index.js’中
import Layout from '../components/MyLayout.js'
import Link from 'next/link'
const PostLink = (props) => (
<li>
<Link href={`/post?title=${props.title}`}>
<a>{props.title}</a>
</Link>
</li>
)
export default () => (
<Layout>
<h1>My Blog</h1>
<ul>
<PostLink title="Hello Next.js"/>
<PostLink title="Learn Next.js is awesome"/>
<PostLink title="Deploy apps with Zeit"/>
</ul>
</Layout>
)
一旦你添加这些内容,你就会看到如下页面
下面,点击第一个链接,你会得到404的页面。没关系,这个页面的URL是什么?
答案是:/post?title=Hello%20Next.js,(译者注:但我自己跑完后却是/post?title=Hello Next.js,并未进行编码)
通过查询字符来传递数据
我们通过查询字符参数来传递数据,在我们呢的例子中,这个参数就是“title”,我们通过使用 PostLink 组件来处理,代码如下:(看一下<Link>中'href'这个特性)
const PostLink = (props) => (
<li>
<Link href={`/post?title=${props.title}`}>
<a>{props.title}</a>
</Link>
</li>
)
就是这样,你可以在查询字符串中传递任何数据类型.
创建“帖子”的页面
现在我们需要创建一个帖子的详情页面来显示博客内容,为了实现这个,我们需要从查询字符串中得到"title"值。我们看看如何实现:
创建一个文件名为:“pages/post.js”的文件,并且添加如下代码:
import {withRouter} from 'next/router'
import Layout from '../components/MyLayout.js'
const Page = withRouter((props) => (
<Layout>
<h1>{props.router.query.title}</h1>
<p>This is the blog post content.</p>
</Layout>
))
export default Page
现在我们的页面就会是如下所示:
那么以上代码发生了什么:
- 我们从"next/router"导入并且使用"withRouter"函数,这个函数将以'router'作为属性注入Next.js
- 这里,我们使用'router'的'query'对象来查询字符串参数
- 因此,我们就可以用'props.router.query.title'来得到这个'标题'
让我们对这个应用做一个简单的修改,用如下代码替换'pages/post.js'文件中的内容
import {withRouter} from 'next/router'
import Layout from '../components/MyLayout.js'
const Content = (props) => (
<div>
<h1>{props.router.query.title}</h1>
<p>This is the blog post content.</p>
</div>
)
const Page = withRouter((props) => (
<Layout>
<Content />
</Layout>
))
export default Page
访问'http://localhost:3000/post?title=hello%20Next.js'这个地址看看会发生什么?
答案是:It throws an error
withRouter
如你所见,代码回抛出一个错误,就像这样:
这是因为我们通过'withRouter'来注入'router'这个属性到'Page'组件中(译者注:即router只能在当前的上下文环境——组件中使用,不可以通过props传递),'withRouter'对象可以用在你的Next.js中的任何地方。所以在这个例子中我们吧'withRouter'放到'Content'组件中
import {withRouter} from 'next/router'
import Layout from '../components/MyLayout.js'
const Content = withRouter((props) => (
<div>
<h1>{props.router.query.title}</h1>
<p>This is the blog post content.</p>
</div>
))
const Page = (props) => (
<Layout>
<Content />
</Layout>
)
export default Page
最后
我们学习了如何通多使用查询字符来创建动态页面,这仅仅是一个开始。
一个动态页面也许会需要更多的信息来渲染,并且我们也许不能通过查询字符这个手段来传递所有的数据。或者说我们需要一个比较干净清楚的URLs,比如这样:
http://localhost:3000/blog/hello-nextjs
所有的这些我们将要在接下来的课程中学习,本节课只是下节课的基础。