快速入门:使用 Next.js 来开发 React 的同构应用

提及 服务端渲染(ssr) 和 SPA,相信你总能说个一二:css

  • 与 服务端渲染(ssr) 相比,SPA 这样的架构设计可让先后端开发并行进行,职责清晰。
  • 与 SPA 相比,服务端渲染(ssr) 首屏等待更短
  • 与 SPA 相比,服务端渲染(ssr) 是服务端直接返回完整的 html 内容,有利于网站的 SEO

这二者的优缺点都很明显,因此随着时代的进步和技术的演变,诞生了 SSR + SPA 的新模式。而且在 react/vue 等前端框架相结合 node (ssr) 下,能够最大限度的重用代码(同构),减小开发维护成本。html

什么是同构应用

未命名文件 (5).jpg

web 应用能够分为 浏览器端服务器端 两部分,对于同构应用来讲,分为 初次发送请求( SSR )后续操做( SPA )前端

  • 初次发送请求 时,服务器端负责渲染页面的所有内容,而后返回给浏览器端,浏览器只须要直接显示返回的内容,因此首屏渲染的速度会很是快;
  • 浏览器端的 后续操做 则再也不须要服务器端的介入,也不会引发页面的刷新,全部的 UI 操做在前端完成。

基于 React 能够在服务端渲染的能力,Next 提供了一套完整且方便的同构应用解决方案。vue

开始 Next.js

Next.js,这是一个 React 的同构应用开发框架。node

建立一个 Next.js 应用

咱们用 CLI 工具 -- Create Next App 来快速建立 Next.js 应用,经过配置参数 -e, --example [name]|[github-url] 能够直接以 Next.js Repo中的模版建立应用:react

npx create-next-app nextjs-auth0 --example "https://github.com/vercel/next.js/tree/master/examples/auth0"
复制代码

咱们今天使用 Next.js 的入门模版(默认):git

npx create-next-app my-nextjs
复制代码

运行成功后,进入 my-nextjs 目录,运行启动命令,应用默认运行在 3000 端口:github

cd my-nextjs
npm run dev
复制代码

http://localhost:3000/, 查看页面源代码,能够发现全部的内容都是服务器端返回的: next-source.pngweb

Pages 页面

Next.js 在开发时遵循了必定的约定:npm

  • 全部的页面必须放在 pages 目录下,页面做为一个组件。
  • 页面与基于其文件名的路由相关联。
    • pages/index.js 关联的路由是 /
    • pages/posts/first-post.js 关联的路由是 /posts/first-post
  • page 具备静态方法 getInitialProps,能够获取接口数据做为组件的 props

建立页面

page/index.js 已经存在,咱们新建一个 pages/posts/first-post.js :

export default function FirstPost() {
  return <h1>First Post</h1>;
}
复制代码

这时候,你访问 http://localhost:3000/posts/first-post, 应该能够看到:

页面间的导航

<Link> 组件能够在客户端实现页面间的导航,和 React Router 同样实现的是前端路由,不会引发页面的刷新:

import Link from "next/link";
复制代码

使用时,将 Link 包裹在 a 标签外,好比在 posts/first-post 添加一个回首页的连接:

import Link from "next/link";

export default function FirstPost() {
  return (
    <> <h1>First Post</h1> <h2> <Link href="/"> <a>Back to home</a> </Link> </h2> </>
  );
}
复制代码

Link 组件默认在后台预取目标页面。 经过设置 prefetch={false} (默认为 true ) 能够禁止页面预取。当 prefetch 被设置为 false 时,鼠标悬停在 上时仍然会触发预取。预取功能只在生产环境中开启。

<Link href="/posts/first-post" prefetch={false}>
  <FirstPost />
</Link>
复制代码

Link 组件的默认行为是将新 URL 推送到 history 堆栈中,可使用 replace 来替换 URL,而不是新增,这样发生跳转后,将没法后退到上一个页面。

<Link href="/about" replace>
  <a>About us</a>
</Link>
复制代码

Next.js 支持具备动态路由的 pages(页面)。例如,若是你建立了一个命名为 pages/posts/[id].js 的文件,那么就能够经过 posts/1posts/2 等相似的路径进行访问。

静态文件服务

若是你添加了一张图片到 public/me.png 路径,经过 /me.png 能够直接访问到它:

import Image from "next/image";

function Avatar() {
  return <Image src="/me.png" alt="me" width="64" height="64" />;
}

export default Avatar;
复制代码

public 目录映射静态文件,包括 robots.txtfavicon.ico、Google 站点验证文件以及任何其它静态文件(包括 .html 文件)。

注意:

  • 请勿为 public 更名。此名称是写死的,不能修改,而且只有此目录能过够存放静态资源并对外提供访问。
  • 请确保静态文件中没有与 pages/ 目录下的文件重名的,不然这将致使错误。

动态加载页面(Lazy loading)

动态加载(Lazy loading)是一种仅在资源须要时加载它们的策略。Next.js 也提供了 import dynamic from "next/dynamic" 帮助咱们实现动态加载策略。

普通 import 一个组件:

import Link from "next/link";
import Hello from "../../component/Hello";

export default function FirstPost() {
  return (
    <> <h1>First Post</h1> <Hello /> <h2> <Link href="/"> <a>Back to home</a> </Link> </h2> </>
  );
}
复制代码

动态加载一个组件:

import Link from "next/link";
import dynamic from "next/dynamic";
// import Hello from "../../component/Hello";

const DynamicComponent = dynamic(() => import("../../component/Hello"));

export default function FirstPost() {
  return (
    <> <h1>First Post</h1> <DynamicComponent /> <h2> <Link href="/"> <a>Back to home</a> </Link> </h2> </>
  );
}
复制代码

从 network 能够看出,动态加载的状况下,Hello 组件被做为了单独资源: 未命名文件 (6).jpg

相关文章
相关标签/搜索