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

相关推荐
我要洋人死8 分钟前
导航栏及下拉菜单的实现
前端·css·css3
科技探秘人19 分钟前
Chrome与火狐哪个浏览器的隐私追踪功能更好
前端·chrome
monkey_meng20 分钟前
【Rust中的迭代器】
开发语言·后端·rust
科技探秘人20 分钟前
Chrome与傲游浏览器性能与功能的深度对比
前端·chrome
余衫马23 分钟前
Rust-Trait 特征编程
开发语言·后端·rust
JerryXZR25 分钟前
前端开发中ES6的技术细节二
前端·javascript·es6
monkey_meng26 分钟前
【Rust中多线程同步机制】
开发语言·redis·后端·rust
七星静香27 分钟前
laravel chunkById 分块查询 使用时的问题
java·前端·laravel
q24985969330 分钟前
前端预览word、excel、ppt
前端·word·excel
小华同学ai35 分钟前
wflow-web:开源啦 ,高仿钉钉、飞书、企业微信的审批流程设计器,轻松打造属于你的工作流设计器
前端·钉钉·飞书