6. Next.js实战开发,Server Components应该如何保存状态?

如果想通过专栏的形式查看本次项目实践可以点击查阅Next 图册目实践

有了之前的Next.js 基础铺垫,我们现在就可以进入花瓣发现页面的功能开发。本文中的代码只列举出关键的内容,进行讲解。更多源码请查阅github.com/rexleimo/re...的v4.0分支进行查阅。

通过之前的栏目学习,梦兽在UI组件库中选择的是微软的Fluent进行项目实战。本文主要分析在不用浏览器客户端api的情况下,Server Components如何保存状态。

页面分析

通过页面分析,我们发现,在花瓣发现页中可以区分6个颜色大区域的组件。本文将以蓝色,橙色,灰色区域进行讲解。也就是我们看到的黄色区域。

javascript 复制代码
// app/page.tsx
// 我们在组件修改成一些代码 具体代码请到上面提到的github地址进行调整
return (
    <>
      <Header {...searchParams}  />

      <div className="flex m-3">
        <div className="w-auto flex items-center border border-solid border-gray-100 rounded p-2">
          <Link>
            采集
          </Link>
          {/* .... */}
        </div>
        <div className='flex flex-auto justify-center'>
          <div className=' grid grid-cols-6 gap-4 ml-4 max-w-[500px]'>
            <Link>推荐</Link>
             {/* .... */}
          </div>
        </div>

        <div className='w-[180px]'>
          <Select>
            <option value="1">综合排序</option>
            <option value="2">时间排序</option>
          </Select>
        </div>
      </div >
      
      <ImageList />
    </>
)

我们看到花瓣页面发现中,发现一个功能,就是点击画板的时候会有一个灰色的状态。在点击中间区域的推荐时候也会有一个黑色的选中状态。

如果现在是开发spa的应用,我们很容易会使用一下js状态库或者useState。但是现在我们使用的是Server Components,这些方法都无法使用,那我们该如何保存状态呢?

状态保存

由于http是没有状态的,我们在没用useState的情况下,浏览器客户端于服务端之间有什么方式进行保留状态呢?

在web应用开发中,我们通常使用cookie来保存状态。

1.cookie

cookie是浏览器提供的一种机制,用于在浏览器和服务器之间传递状态。http协议是无状态的,也就是说,在http协议中,客户端和服务器之间没有维持状态的机制。

但是,cookie是一种机制,它允许在浏览器和服务器之间传递状态。当浏览器向服务器发出请求时,服务器会向浏览器发送一个cookie。浏览器会将cookie保存在本地,并在下次请求时将cookie发送给服务器。

2. http 报文

我们都知道浏览器和服务端就是通过http报文进行通信的,如果我们收到服务端的报文状态,那么我们就可以在下次请求的时候带上这个状态一起发送到服务端。就能实现了状态的保存。

代码改造

这里主要看注解的代码。

typescript 复制代码
export default async function Home({ searchParams }: {
  searchParams: {
    query: string,
    cate: string,
    search: string
  }
}) {

 // 判断是否点击了采集/画板
  const queryClsxName = (query: string) => clsx(
    {
      'bg-slate-200': searchParams.query === query,
    },
    'rounded', 'p-1')
//  判断是否点击了 推荐,游戏等
  const cateClsxName = (cate: string) => clsx({
    'bg-slate-900': searchParams.cate === cate,
    'text-white': searchParams.cate === cate
  }, 'rounded', 'p-3', 'text-center')
// 点击调整的时候把上一次http协议中参数(searchParams)一起发送到服务端进行ssr html渲染
  const queryParamsSet = (newQuery: { [x: string]: string }) => {
    const newSearchParams = new URLSearchParams({
      query: searchParams.query,
      cate: searchParams.cate,
      search: searchParams.search,
      ...newQuery
    })
    return newSearchParams.toString();
  }

  return (
    <>
      <Header {...searchParams}  />

      <div className="flex m-3">
        <div className="w-auto flex items-center border border-solid border-gray-100 rounded p-2">
          <Link href={`?${queryParamsSet({ query: 'design' })}`} className={queryClsxName('design')}>
            采集
          </Link>

          <Link href={`?${queryParamsSet({ query: 'boards' })}`} className={queryClsxName('boards')}>
            画板
          </Link>
        </div>
        <div className='flex flex-auto justify-center'>
          <div className=' grid grid-cols-6 gap-4 ml-4 max-w-[500px]'>
            <Link className={cateClsxName('推荐')} href={`?${queryParamsSet({ cate: '推荐' })}`}>推荐</Link>
            <Link className={cateClsxName('UI_UX')} href={`?${queryParamsSet({ cate: 'UI_UX' })}`} >UI/UX</Link>
            <Link className={cateClsxName('平面')} href={`?${queryParamsSet({ cate: '平面' })}`} >平面</Link>
            <Link className={cateClsxName('摄影')} href={`?${queryParamsSet({ cate: '摄影' })}`}>摄影</Link>
            <Link className={cateClsxName('游戏')} href={`?${queryParamsSet({ cate: '游戏' })}`} >游戏</Link>
          </div>
        </div>

        <div className='w-[180px]'>
          <Select>
            <option value="1">综合排序</option>
            <option value="2">时间排序</option>
          </Select>
        </div>
      </div >
      
      <ImageList />
    </>
  )
}

我们现在来看看成果

20230909-223131.gif

感谢你的阅读,期待在下一篇文章中再次见到你!

这里是梦兽编程,本次的代码更新将会放在Github本次项目的Github连接中的V3.0分支中

我的B站视频号更多视频动态。

截屏2023-08-18 00.02.24.png

本文使用 markdown.com.cn 排版

相关推荐
学习使我快乐0122 分钟前
JS进阶 3——深入面向对象、原型
开发语言·前端·javascript
bobostudio199523 分钟前
TypeScript 设计模式之【策略模式】
前端·javascript·设计模式·typescript·策略模式
黄尚圈圈1 小时前
Vue 中引入 ECharts 的详细步骤与示例
前端·vue.js·echarts
浮华似水2 小时前
简洁之道 - React Hook Form
前端
2401_857622664 小时前
SpringBoot框架下校园资料库的构建与优化
spring boot·后端·php
正小安4 小时前
如何在微信小程序中实现分包加载和预下载
前端·微信小程序·小程序
2402_857589364 小时前
“衣依”服装销售平台:Spring Boot框架的设计与实现
java·spring boot·后端
哎呦没6 小时前
大学生就业招聘:Spring Boot系统的架构分析
java·spring boot·后端
_.Switch6 小时前
Python Web 应用中的 API 网关集成与优化
开发语言·前端·后端·python·架构·log4j
一路向前的月光6 小时前
Vue2中的监听和计算属性的区别
前端·javascript·vue.js