next.js 服务端组件 -客户端组件

Next.js 概述

Next.js是一个基于React的框架,具有服务器端渲染能力。 它非常快速和SEO友好。

使用Next.js,您可以轻松创建强大的基于React的应用程序并对其进行测试。 以下是Next.js的主要功能。

  • 热代码重新加载 Next.js服务器检测到修改的文件并自动重新加载它们。

  • 自动路由 无需为路由配置任何URL。 文件应放置在pages文件夹中。 所有URL将映射到文件系统。 可以进行自定义。

  • 组件特定样式 styled-jsx提供对全局和组件特定样式的支持。

  • 服务器端呈现 React组件在服务器上预渲染,因此在客户端加载速度更快。

  • 节点生态系统 Next.js是基于React的,与Node生态系统很好地结合在一起。

  • 自动代码拆分 Next.js使用它们需要的库来渲染页面。 Next.js不是创建单个大型javascript文件,而是创建多个资源。 加载页面时,只会加载所需的javascript页面。

  • 预取 Next.js提供了Link组件,用于链接多个支持预取页面资源的组件。

  • 动态组件 Next.js允许动态导入JavaScript模块和React组件。

  • 导出静态站点 Next.js允许从您的Web应用程序中导出完整的静态站点。

  • 内置TypeScript支持 Next.js是用TypeScript编写的,并提供出色的TypeScript支持。

服务端组件

next.js 提供了服务端组件,它允许你在服务端渲染组件, 而不依赖与浏览器环境。服务端组件可以分为两种模式:

  • 静态渲染
  • 动态渲染

静态渲染

默认情况下,所有服务端组件都是静态渲染的。 使用静态渲染时,next.js会将渲染结果缓存起来,并可以推送到CDN、redis等缓存中,以提高性能。

动态渲染

所谓的动态渲染其实就是在渲染之前进行了数据请求,或者使用到了next.js的server api, 比如:

  • fetch(),使用fetch()获取数据
  • headers(), 使用headers()获取请求头中的信息
  • cookies(),使用cookies()获取cookie中的信息
  • searchParams,使用searchParams获取url中的query参数 这些api后续会单独讲解,这里先简单了解一下即可。

由于这些数据是运行时才能获取到的,并不能在编译阶段获取,所以这些数据没办法被静态缓存。

服务端渲染的优势

  • 缓存:在服务器端渲染的结果获取请求的数据,都可以缓存并在后续请求和用户之间重复使用。这可以通过复用重复的请求和渲染结果来提高性能。
  • bundle的大小,由于服务端组件不需要使用浏览器api,也就是没有额外的js文件,所以bundle的大小会小很多。
  • seo:服务端组件会将数据渲染到html中,所以可以更好的被搜索引擎收录。
  • 流式渲染:服务器组件允许你将内容拆分为多个块,并在渲染完成之后将它们流式传输到客户端。这其实就是允许用户更早地看到页面的某些部分,而不必等待整个页面在服务器上呈现。

避免使用浏览器api

虽然next.js支持组件在服务端进行渲染,但是如果你在服务端组件中使用了浏览器api,那么会导致服务端组件无法正常渲染。

这一点在开发中很容易被忽略,各位小伙伴可以多注意一下。

use server

next.js默认就是server component,但是并不会在编写代码时提示错误使用api的风险。为了避免我们使用浏览器api,next.js提供了use server关键字,它可以帮助我们检测到不安全的api使用。

"use server"

export default function Home() {
    const [count, setCount] = useState(0);
    // 由于server端不允许使用react/client 相关的api,所以这里会报错

    useEffect(() => {
    }, [])

    return <div>{count}</div>;
}

客户端组件

客户端组件允许您在服务器上编写可交互的 UI,并可以使用浏览器api.

服务端渲染的特点

  • 交互性:客户端组件可以使用useState、useEffect等 React Hook。
  • 浏览器 API:客户端组件可以访问浏览器 API,例如 window、document 等。
  • hydrate:由于服务端渲染的组件是静态的,因此在客户端渲染时,还需要加载js文件,使得组件能够与进行交互。

use client

"use client" 用于声明当前组件为客户端组件。

在服务端组件中,你可以使用react/client相关的的api, 同时你也可以使用浏览器 api。

但是, "use client" 的文件中所有的模块都会被打包进 bundle 中。因此,我们应该尽可能地减少客户端组件的使用,进而减少bundle的体积。

'use client'

import { useState } from 'react'
 
export default function Counter() {
  const [count, setCount] = useState(0)
 
  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>Click me</button>
    </div>
  )
}

避免嵌套服务端组件

客户端组件中是禁止嵌套服务端组件的,但是服务端组件中是可以嵌套客户端组件。

混合组件模式

在构建 next.js 应用程序时,您需要区分代码应该编造在服务端还是客户端。

服务端组件和客户端组件的使用时机

场景服务端客户端
请求接口
操作node api
访问浏览器 api
使用react hooks
使用react class components

混合使用

import { useState } from 'react'
import { Carousel } from 'acme-carousel'
 
export default function Gallery() {
    let [isOpen, setIsOpen] = useState(false)
    
    return (
        <div>
            <button onClick={() => setIsOpen(true)}>View pictures</button>
            {isOpen && <Carousel />}
        </div>
    )
}

上述的代码其实会报错,因为默认情况下,所有的组件都是服务端组件,由于服务端组件不能使用react hooks, 所以会报错。 因此我们需要对此进行改造

  • Gallery
  • Carousel
import CarouselComponent from './CarouselComponent';
export default function Gallery() {
    return (
        <div>
            <CarouselComponent />
        </div>
    )
}

上述的改造中,其实就是一种服务端组件嵌套客户端组件的模式,这种方式是允许的,相反客户端组件嵌套服务端组件不被允许。

'use client'
 import ServerComponent from './Server-Component'
 
export default function ClientComponent({ children }) {
  const [count, setCount] = useState(0)
  return (
    <>
      <button onClick={() => setCount(count + 1)}>{count}</button>
      <ServerComponent />
    </>
  )
}

上述代码中,ServerComponent 是服务端组件,因此不能在客户端组件中引入,所以会报错。 我们也可以通过插槽的方式,将服务端组件嵌套在客户端组件中,这种方式是允许的。

  • client-component
  • server-component
'use client'
import { useState } from 'react'
export default function ClientComponent({ children }) {
    const [count, setCount] = useState(0)
    return (
        <>
            <button onClick={() => setCount(count + 1)}>{count}</button>
            {children}
        </>
    )
}
  • 20
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

向想享xh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值