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 排版

相关推荐
码事漫谈3 小时前
大模型输出的“隐性结构塌缩”问题及对策
前端·后端
小江的记录本3 小时前
【网络安全】《网络安全常见攻击与防御》(附:《六大攻击核心特性横向对比表》)
java·网络·人工智能·后端·python·安全·web安全
这儿有一堆花3 小时前
前端三件套真的落后了吗?揭开现代 Web 开发的底层逻辑
前端·javascript·css·html5
努力的小雨3 小时前
龙虾量化实战法(QClaw)
后端
.Cnn3 小时前
JavaScript 前端基础笔记(网页交互核心)
前端·javascript·笔记·交互
橙露4 小时前
SpringBoot 整合 MinIO:分布式文件存储上传下载
spring boot·分布式·后端
醉酒的李白、4 小时前
Vue3 组件通信本质:Props 下发,Emits 回传
前端·javascript·vue.js
anOnion4 小时前
构建无障碍组件之Window Splitter Pattern
前端·html·交互设计
NotFound4864 小时前
实战分享Python爬虫,如何实现高效解析 Web of Science 文献数据并导出 CSV
前端·爬虫·python
徐小夕4 小时前
PDF无限制预览!Jit-Viewer V1.5.0开源文档预览神器正式发布
前端·vue.js·github