next.js基础教程

next.js是一个极简的服务端渲染react的框架。

安装

1
npm install next react react-dom --save

添加scriptpackage.json里:

1
2
3
4
5
6
7
{
"scripts": {
"dev": "next",
"build": "next build",
"start": "next start"
}
}

next.js的路由是基于文件系统,每一个./pages/*.js都会变成一个路由。
新建一个./pages/index.js文件:

1
2
3
export default () => (
<div>Welcome to next.js!</div>
)

然后执行npm run dev,然后打开浏览器http://localhost:3000/就可以看到页面了。如果要设置指定端口,使用npm run dev -- -p <your port here>

至此为止,我们实现了:

  • 自动解析es2015代码,打包压缩构建(使用webpackbabel
  • 热更新
  • 服务端渲染
  • 静态文件服务器(./static/文件里面)

是不是很神奇,以前要实现这些功能需要配置很多文件,webpack.conf.js.babelrc,可能还需要koa或者express框架配合。现在只要一个包就可以了。

可能会感到奇怪,项目根本就没有html文件,怎么一个js就可以输出页面了,要是我想改title怎么办?直接出html是因为next内置了一个document组件,可以输出完整html,而head组件,可以将自定义的head内容追加到页面。

1
2
3
4
5
6
7
8
9
10
import Head from 'next/head'
export default () => (
<div>
<Head>
<title>My page title</title>
<meta name="viewport" content="initial-scale=1.0, width=device-width" />
</Head>
<p>Hello world!</p>
</div>
)

组件unmounthead将会被销毁。

CSS

html解决了,那css怎么办呢?难道只能写内联样式?next也内置支持基础的css

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
export default () => (
<div className='hello'>
<p>Hello World</p>
<style jsx>{`
.hello {
background: #eee;
padding: 100px;
text-align: center;
}
.hello:hover {
background: #ccc;
}
`}</style>
</div>
)

路由

可以使用link组件实现客户端路由之间的跳转,之所以说客户端路由是因为页面并没有刷新。

1
2
3
4
5
6
7
8
9
// pages/index.js
import Link from 'next/link'
export default () => (
<div>Click <Link href="/about"><a>here</a></Link> to read more</div>
)
// pages/about.js
export default () => (
<p>Welcome to About!</p>
)

router

也可以使用router组件来实现跳转:

1
2
3
4
5
6
7
8
import Router from 'next/router'

export default () => (
<div>
Click <span onClick={() => Router.push('/about')}>here</span>
to read more
</div>
)

获取数据

有时候页面需要加载一下数据,这个时候可以在getInitialProps这个异步静态方法中添加:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import React from 'react'
import 'isomorphic-fetch'
export default class extends React.Component {
static async getInitialProps ({ req }) {
const res = await fetch('https://api.github.com/repos/zeit/next.js')
const json = await res.json()
return req
? { userAgent: req.headers['user-agent'], stars: json.stargazers_count }
: { userAgent: navigator.userAgent, stars: json.stargazers_count }
}
render () {
return <div>
Hello World {this.props.userAgent}
<div>Next stars: {stars}</div>
</div>
}
}

getInitialProps函数的返回值一定是一个对象,这个对象会当做组件的一个props,当输入url打开页面时,getInitialProps函数会由服务端渲染,而通过路由客户端加载的页面,会由客户端来执行,上面的例子中userAgent一个就是http请求拿到的,另一个就是浏览器拿到的。getInitialProps函数只能在page路由页面中添加,在子组件中是不能使用的。

坚持原创技术分享,您的支持将鼓励我继续创作!