豪翔天下

Change My World by Program

0%

Next.js 手册

  • ReactSSR框架

基础配置

1
next -p 3001	# 指定启动端口

next.config.js

1
2
3
4
5
module.exports = {
env: { // 设置环境变量,设置后可以在jsx中直接用{process.env.customKey}获取值
customKey: 'my-value',
}
}

路由

1
2
3
4
5
6
7
8
import { useRouter } from 'next/router'

const router = useRouter() // 等同于window.location
router.pathname // 获取路由路径
router.query.search // 获取query参数
router.locale // 当前的locale
router.locales // 所有的locales
router.defaultLocale // 默认的locale

页面组件

  • 可以在Head里面插入全局的js,例如google analytics代码:

    1
    2
    3
    4
    5
    6
    7
    <Head>
    <script
    dangerouslySetInnerHTML={{
    __html: `[google analytics tracking code here]`
    }}
    />
    </Head>

Image

  • 可以设置width、height、quality、priority、responsive自动修改图片显示大小
  • 但是毕竟是后端js程序在进行转换,不如直接使用cloudinary这样的服务速度快功能多
1
<Link href=''><a>title</a></Link>

后端渲染SSR

  • 在组件加载前就从接口获取数据,才能实现后端渲染,而不是前端去调用API
  • 需要注意的是通过服务端获取的props,必须直接传递到html中去,不要用useEffect等去传递给另外一个变量,那样就不会直接渲染到HTML中去了,浏览网页源代码发现他们只是在一个变量上,对SEO十分不友好
  • getServerSidePropsgetInitialProps都无法用在404页面上,如果是404页面只能在componentDidMount或者useEffect(() => {}, [])里面去请求获取数据了,官方说明
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
class MyComponent extends React.Components {
static getInitialProps() {
return fetch('').then(response => response.json()) // 需要返回一个字典
}

render() {
return (<div>aaa</div>)
}
}

// 如果是函数式组件可以这样做
function MyComponent() {
return (<div>aaa</div>)
}
MyComponent.getInitialProps = async () => {
return fetch('').then(response => response.json())
}

// 官方推荐的是getServerSideProps,需要注意的是它不能做用于纯component,必须是page
export async function getServerSideProps(){
const data = await myAPI('/api/resource')
return {
props: { data }
}
}

// 如果是不会改变的数据可以用getStaticProps,它会在编译的时候就静态的props传入组件,所以如果接口返回的数据有变化,也只有重新编译才行
export async function getStaticProps() {
const data = await myAPI('/api/resource')
return {
props: { data }
}
}

// 用于在使用动态路由时生成静态文件,他是配合getStaticProps使用的,getStaticProps根据url生成不同的页面
export async function getStatisPaths() {
const res = await myAPI('/api/resource')
const paths = res.data.map(resource => `/resource/${resource.id}`)
return {
paths, // 有多个path就会生成多个静态页面
fallback: false
}
}

export default MyComponent

Hook

一个获取window size的hook

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// hooks/useWindowResize.js
import React, { useLayoutEffect, useState } from 'react';

export default function useWindowResize() {
const [size, setSize] = useState([0, 0]);

useLayoutEffect(() => {
function updateSize() {
setSize([window.innerWidth, window.innerHeight]);
}

window.addEventListener('resize', updateSize);

updateSize();

return () => window.removeEventListener('resize', updateSize);
}, []);
return size;
}

// 其他组件就能这样引用了
const [windowWidth, windowHeight] = useWindowResize();

国际化i18N

  • nextjs的国际化支持很棒,只要设定好需要哪些语言,就只要在切换语言的时候指定语言,而不需要更改页面中其他的地方
  • 支持通过域名来切换语言,或者通过path前缀来切换语言
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// next.config.js
module.exports = {
i18n: {
locales: ['en-US', 'fr', 'nl-NL'], // 声明支持哪些语言
defaultLocale: 'en-US', // 声明默认的语言
domains: [ // 如果想通过域名来确定语言,需要在这里设置域名,如果不设置这个,那么默认是通过path来确定的,例如,默认是/blog,带语言就是/fr/blog,nl-nl/blog
{
domain: 'example.com',
defaultLocale: 'en-US',
},
{
domain: 'example.nl',
defaultLocale: 'nl-NL',
},
{
domain: 'example.fr',
defaultLocale: 'fr',
},
],
},
}

TroubleShooting

  • pages with getServerSideProps can not be exported. 需要将package.json中的build命令中的next export去掉,它和getServerSideProps不兼容
  • getServerSideProps不起作用: 它只能做用于page,不能直接作用于component
坚持原创技术分享,谢谢支持

欢迎关注我的其它发布渠道