Published on

Nextjs数据获取方式

Authors
  • avatar
    Name
    游戏人生
    Twitter

路由处理程序

前后端分离架构中,客户端与服务端通过 API 接口进行交互,在 Nextjs 中,就称为路由处理程序。

实现方式

使用路由处理程序,必须在 app 目录下创建对应的 route.js 文件,而且不能与页面的 page.js 在同一层级。

示例:

  app
  |- user
    |- page.js
  |- api
    |- user
      |- route.js
  |- layout.js

app/api/user/route.js 即为 user 页面路由处理程序。其路径为 /api/user

user/page.js 代码如下:

import { useState, useEffect } from 'react';

export default function User() {

  const [userDetail, setUserDetail] = useState({});

  userEffect(() => {
    fetch('/api/user')
      .then(res => res.json())
      .then(data => setUserDetail(data))
  }, [])

  return (
    <div>
      <h1>User Detail</h1>
      <div>
        {userDetail?.username}
      </div>
    </div>
  )
}

route.js 代码如下:

  import { NextResponse } from 'next/server';
  import {
    AddUserValidation,
  } from '@/validations/UserValidation';

  // GET 操作
  export async function GET() {
  
    return NextResponse.json({ username: 'Lily', age: 21 });
  }

  /**
   * POST 操作
   */
  export const POST = async (request: NextRequest) => {

  const json = await request.json();

  const parse = AddUserValidation.safeParse(json);

  if (!parse.success) {
    return NextResponse.json(parse.error.format(), { status: 422 });
  }

  const { username, age } = parse.data;

  try {

    //  user 数据插入数据库
    const id = await addUser({username, age});

    return NextResponse.json({ id });
  } catch (error) {
    return NextResponse.json({
      success: false,
    }, { status: 500 });
  }
};

缓存行为

默认缓存

在 v15 版本之前,默认情况下,使用 Response 或者 NextResponse 的 GET 请求会被缓存。

示例,新建 app/api/time/route.js,代码如下:

  export async function GET() {
    return Response.json({ data: new Date().toLocaleTimeString() });
  }

在浏览器访问该路径 /api/time,会返回时间信息,dev 环境下,刷新浏览器,时间会更新;但是在生成版本的情况下, 时间不会发生改变,即被缓存了。

设置缓存时间

为了控制缓存,可以设置缓存的时效,适用于一些重要性低、时效性低的页面。

有两种方式:

  • 一种事使用路由段配置项
  • 另一种是使用 next.revalidate 选项

路由段配置项: 修改 app/api/time/route.js,代码如下:

export const revalidate = 10;

export async function GET() {
  return Response.json({ data: new Date().toLocaleTimeString() });
}

export const revalidate = 10 表示设置重新验证频率为 10s,但是并不是设置服务器每 10s 会自动更新一次 /api/time。 而是最少 10s 后才重新验证。即:

超过 revalidate 设置时间的首次访问会触发缓存更新,如果更新成功,后续的返回就是新的内容,直到下一次触发缓存更新