TL;DR
今日は Next.js と TypeScript を用いて、Web Storage API を使ったブックマーク機能の実装方法について深堀りしていきます。
開発環境 | バージョン |
---|---|
Next.js | 13.4.4 |
TypeScript | 5.0.4 |
Emotion | 11.11.0 |
React | 18.2.0 |
Web Storage API とは?
Web Storage API は、ウェブブラウザ上でキーと値のペアを保存するための API です。ブラウザ上でデータを保存したい場合、一般的には 2 つの方法、"localStorage" と "sessionStorage" があります。どちらも同じ Web Storage API を使用しますが、その振る舞いには微妙な違いがあります。
- localStorage: こちらはウェブページのセッション間(ブラウザを閉じて再開するなど)でもデータを保持します。つまり、永続的なデータストレージとなります。
- sessionStorage: こちらは現在開いているページのセッション中だけデータを保持します。ページやブラウザを閉じるとデータは消えてしまいます。
これらの特性を利用して、ブックマーク機能のようなユーザー固有のデータを保存する場合によく用いられます。
簡単な localStorage の使用例を見てみましょう。
// データの保存
localStorage.setItem('myKey', 'myValue')
// データの取得
const data = localStorage.getItem('myKey') // myValue
Next.js で、Web Storage API でブックマーク機能を実装
では、Next.js の環境でブックマーク機能を実装してみましょう。
ファイル名: Bookmark.tsx
import { useState, useEffect } from 'react'
type Props = {
id: string
}
const Bookmark = ({ id }: Props) => {
const [bookmarked, setBookmarked] = useState(false)
useEffect(() => {
setBookmarked(Boolean(localStorage.getItem(id)))
}, [id])
const toggleBookmark = () => {
if (bookmarked) {
localStorage.removeItem(id)
} else {
localStorage.setItem(id, 'bookmarked')
}
setBookmarked(!bookmarked)
}
return <button onClick={toggleBookmark}>{bookmarked ? 'Remove bookmark' : 'Add bookmark'}</button>
}
ここでは、ブックマークを追加・削除するための Bookmark
コンポーネントを作成しました。コンポーネントはブックマークする項目の id
を受け取ります。
初期化時、useEffect
により localStorage
をチェックし、該当 id
のブックマークが存在するか確認します。存在すれば bookmarked
を true
に設定します。
toggleBookmark
関数は、ボタンがクリックされた時に呼び出され、ブックマークの追加と削除を行います。
Web Storage API でブックマーク機能を実装
今度は、より発展的な例を見てみましょう。
ファイル名: BookmarkList.tsx
import { useState, useEffect } from 'react'
import Bookmark from './Bookmark'
type Post = {
id: string
title: string
}
type Props = {
posts: Post[]
}
const BookmarkList = ({ posts }: Props) => {
const [bookmarks, setBookmarks] = useState<string[]>([])
useEffect(() => {
const storedBookmarks = Object.keys(localStorage)
setBookmarks(storedBookmarks)
}, [])
return (
<ul>
{posts.map((post) => (
<li key={post.id}>
<h2>{post.title}</h2>
<Bookmark id={post.id} />
</li>
))}
</ul>
)
}
ここでは、投稿のリストを受け取り、それぞれの投稿にブックマークボタンを追加する BookmarkList
コンポーネントを作成しました。ページロード時には、localStorage からすべてのブックマークを取得し、それをbookmarks
ステートに設定します。
Emotion で実装
最後に、Emotion を使ってブックマークボタンをスタイリングしてみましょう。
ファイル名: Bookmark.tsx
/** @jsxImportSource @emotion/react */
import { css } from '@emotion/react'
import { useState, useEffect } from 'react'
type Props = {
id: string
}
const buttonStyles = css`
background-color: transparent;
border: none;
cursor: pointer;
padding: 10px;
color: #333;
font-size: 16px;
`
const Bookmark = ({ id }: Props) => {
const [bookmarked, setBookmarked] = useState(false)
useEffect(() => {
setBook
marked(Boolean(localStorage.getItem(id)))
}, [id])
const toggleBookmark = () => {
if (bookmarked) {
localStorage.removeItem(id)
} else {
localStorage.setItem(id, 'bookmarked')
}
setBookmarked(!bookmarked)
}
return (
<button css={buttonStyles} onClick={toggleBookmark}>
{bookmarked ? 'Remove bookmark' : 'Add bookmark'}
</button>
)
}
ここでは、Emotion の css
関数を使ってスタイルを定義し、そのスタイルをボタンに適用しています。
以上の例からわかるように、Web Storage API はブラウザにデータを保存し、ページを離れてもデータが残るようにする機能です。Next.js と TypeScript を使うと、この API を使ってユーザーのブックマークを管理する機能を簡単に実装できます。