current branch 對應如下文檔
redis
ioredis
本專欄內容均可在Github:notes_01 找到
一、效果
完整項目使用技術棧:
Nextjs15 + MySQL + Redis + Auth + Prisma + i18n + strapi + Docker + vercel
二、修改根布局和其他頁面
修改 app/page.tsx:
// app/page.js
export default async function Page() {return (<div className="note--empty-state"><span className="note-text--empty-state">Click a note on the left to view something! 🥺</span></div>);
}
修改 app/layout.tsx:
import "./style.css";
import Sidebar from "@/components/Sidebar";export default async function RootLayout({ children }) {return (<html lang="en"><body><div className="container"><div className="main"><Sidebar /><section className="col note-viewer">{children}</section></div></div></body></html>);
}
新建 app/components/Sidebar.tsx,代碼為:
import React from "react";
import Link from "next/link";export default async function Sidebar() {return (<><section className="col sidebar"><Link href={"/"} className="link--unstyled"><section className="sidebar-header"><imgclassName="logo"src="/logo.svg"width="22px"height="20px"alt=""role="presentation"/><strong>React Notes</strong></section></Link><section className="sidebar-menu" role="menubar">{/* SideSearchField */}</section><nav>{/* SidebarNoteList */}</nav></section></>);
}
Copy: app/style.css 內容
如果步驟正確的話,此時再訪問 http://localhost:3000/ 應該效果如下:
三、使用 redis
使用 Redis 很簡單,一共分為三步:
1、安裝 redis
# macos
brew install redis
2、啟動 redis
redis-server
3、使用 ioredis
pnpm i ioredis
四、 redis 的 CURD
新建 lib/redis.ts 代碼如下:
import Redis from "ioredis";/*** 創建 Redis 客戶端實例* 默認連接到本地 Redis 服務器 (localhost:6379)*/
const redis = new Redis();/*** 初始數據* 當 Redis 中沒有數據時,使用這些數據初始化* 每條筆記包含:* - title: 標題* - content: 內容* - updateTime: 更新時間*/
const initialData = {"1702459181837":'{"title":"sunt aut","content":"quia et suscipit suscipit recusandae","updateTime":"2023-12-13T09:19:48.837Z"}',"1702459182837":'{"title":"qui est","content":"est rerum tempore vitae sequi sint","updateTime":"2023-12-13T09:19:48.837Z"}',"1702459188837":'{"title":"ea molestias","content":"et iusto sed quo iure","updateTime":"2023-12-13T09:19:48.837Z"}',
};/*** 獲取所有筆記* 如果 Redis 中沒有數據,則使用初始數據* @returns Promise<Record<string, string>> 所有筆記的哈希表*/
export async function getAllNotes() {const data = await redis.hgetall("notes");if (Object.keys(data).length == 0) {await redis.hset("notes", initialData);}return await redis.hgetall("notes");
}/*** 添加新筆記* @param data 筆記數據(JSON 字符串)* @returns Promise<string> 新筆記的 UUID*/
export async function addNote(data: any) {const uuid = Date.now().toString();await redis.hset("notes", [uuid], data);return uuid;
}/*** 更新指定筆記* @param uuid 筆記的唯一標識符* @param data 更新的筆記數據(JSON 字符串)*/
export async function updateNote(uuid: string, data: any) {await redis.hset("notes", [uuid], data);
}/*** 獲取指定筆記* @param uuid 筆記的唯一標識符* @returns Promise<object> 筆記數據對象*/
export async function getNote(uuid: string) {return JSON.parse((await redis.hget("notes", uuid)) || "{}");
}/*** 刪除指定筆記* @param uuid 筆記的唯一標識符* @returns Promise<number> 刪除的記錄數*/
export async function delNote(uuid: string) {return redis.hdel("notes", uuid);
}export default redis;
五、修改組件 Sidebar
修改 app/components/Sidebar.tsx 內容為
import React from "react";
import Link from "next/link";
// 新增
import { getAllNotes } from "@/lib/redis";export default async function Sidebar() {// 新增const notes = await getAllNotes();return (<>......<nav>/** 新增 */<SidebarNoteList notes={notes} /></nav></section></>);
}
六、新增 SidebarNoteList
新增 app/components/SidebarNoteList.tsx 代碼:
export default async function NoteList({ notes }) {const arr = Object.entries(notes);if (arr.length == 0) {return <div className="notes-empty">{"No notes created yet!"}</div>;}return (<ul className="notes-list">{arr.map(([noteId, note]) => {const { title, updateTime } = JSON.parse(note);return (<li key={noteId}><header className="sidebar-note-header"><strong>{title}</strong><small>{updateTime}</small></header></li>);})}</ul>);
}
這時候我們打開 http://localhost:3000/ 應為下圖所示:
同時打開 RDM
里面也有了 redis
的數據
下載鏈接 https://redis.tinycraft.cc/zh/
七、處理時間
下載 dayjs 依賴
pnpm i dayjs
修改 app/components/SidebarNoteList.tsx為:
// 新增
import dayjs from "dayjs";
export default async function NoteList({ notes }: { notes: any }) {const arr = Object.entries(notes);......// 新增<small>{dayjs(updateTime).format("YYYY/MM/DD HH:mm:ss")}</small></header></li>);})}</ul>);
}
打開 http://localhost:3000/ 時間變化為:
重要的是我們引用了 day.js
這個庫。我們引入 day.js
的 SidebarNoteList
組件使用的是服務端渲染,這意味著 day.js
的代碼并不會被打包到客戶端的 bundle
中。我們查看開發者工具中的源代碼:
你會發現 node_modules
并沒有 day.js
,但如果你現在在 SidebarNoteList
組件的頂部添加 ‘use client
’,聲明為客戶端組件,你會發現立刻就多了 day.js
:
這就是使用 React Server Compoent
的好處之一,服務端組件的代碼不會打包到客戶端的 bundle
中