Next.js と TypeScript で、ユーザーの閲覧履歴を表示する方法

TwitterFacebookHatena

TL;DR

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 はブラウザ上でデータを安全に保存できる方法の一つです。Web Storage API には、データを一時的に保存する「sessionStorage」や、データを永続的に保存する「localStorage」の 2 つのメイン機能があります。

  • localStorage:データは永続的に保存され、ブラウザを閉じてもデータは消えません。容量は通常 5MB です。
  • sessionStorage:データはセッション中にのみ保存され、ブラウザを閉じるとデータは消えます。容量は通常 5MB です。

使い方は非常に簡単で、以下のように setItemgetItem メソッドを使ってデータを保存、取得できます。

// 保存
localStorage.setItem('key', 'value')

// 取得
const value = localStorage.getItem('key') // 'value'

Next.js で、Web Storage API を実装

この項では、Next.js で、Web Storage API を用いてユーザーの閲覧履歴を表示する具体的な実装を見せます。

ファイル名: pages/index.tsx

import { useEffect, useState } from 'react'

type Props = {
  url: string
}

const HomePage = ({ url }: Props) => {
  const [history, setHistory] = useState<string[]>([])

  useEffect(() => {
    // 過去の閲覧履歴を取得
    const storedHistory = JSON.parse(localStorage.getItem('history') || '[]')
    // 過去の閲覧履歴に新しいURLを追加
    const newHistory = [...storedHistory, url]
    // 閲覧履

    歴を保存
    localStorage.setItem('history', JSON.stringify(newHistory))
    // 閲覧履歴をstateにセット
    setHistory(newHistory)
  }, [url])

  return (
    <div>
      <h1>閲覧履歴</h1>
      <ul>
        {history.map((url, index) => (
          <li key={index}>{url}</li>
        ))}
      </ul>
    </div>
  )
}

export default HomePage

上記コードでは、ページが読み込まれるとき(useEffect 内)に、閲覧履歴を localStorage から取得し、新たな URL を追加して保存しています。そして、それを state にセットして画面に表示しています。

JSON.parse()は JavaScript のビルトイン関数で、JSON 形式の文字列を JavaScript のオブジェクトに変換します。"JSON"は JavaScript Object Notation の略で、データの形式の一つです。

具体的には、次のように動作します:

let jsonStr = '{"name":"John", "age":30, "city":"New York"}'
let obj = JSON.parse(jsonStr)

console.log(obj.name) // "John"
console.log(obj.age) // 30
console.log(obj.city) // "New York"

上記の例では、jsonStrという JSON 形式の文字列をJSON.parse()を使って JavaScript のオブジェクトに変換しています。その結果、生成されたオブジェクトのプロパティにアクセスすることが可能になります。

逆に、JavaScript のオブジェクトを JSON 形式の文字列に変換したい場合にはJSON.stringify()を使います。例えば:

let obj = { name: 'John', age: 30, city: 'New York' }
let jsonStr = JSON.stringify(obj)

console.log(jsonStr) // '{"name":"John","age":30,"city":"New York"}'

これらの関数はデータをサーバーとクライアント間でやり取りしたり、ブラウザのローカルストレージにデータを保存したりする際に非常に便利です。

Web Storage API を実装

次に、localStorage だけでなく、sessionStorage を用いた高度な例を見せます。

import { useEffect, useState } from 'react'

type Props = {
  url: string
}

const HomePage = ({ url }: Props) => {
  const [sessionHistory, setSessionHistory] = useState<string[]>([])

  useEffect(() => {
    // セッション中の閲覧履歴を取得
    const storedHistory = JSON.parse(sessionStorage.getItem('history') || '[]')
    // セッション中の閲覧履歴に新しいURLを追加
    const newHistory = [...storedHistory, url]
    // 閲覧履歴を保存
    sessionStorage.setItem('history', JSON.stringify(newHistory))
    // 閲覧履歴をstateにセット
    setSessionHistory(newHistory)
  }, [url])

  return (
    <div>
      <h1>このセッションでの閲覧履歴</h1>
      <ul>
        {sessionHistory.map((url, index) => (
          <li key={index}>{url}</li>
        ))}
      </ul>
    </div>
  )
}

export default HomePage

ここでは sessionStorage を用いていますので、ユーザーがブラウザを閉じたら閲覧履歴は消えます。これは一時的なデータの保存に適しています。

Emotion で実装

最後に、Emotion を用いて閲覧履歴の表示を美しく整えます。css プロパティを活用して、閲覧履歴のリストにスタイルを適用します。

/** @jsxImportSource @emotion/react */
import { css } from '@emotion/react'
import { useEffect, useState } from 'react'

type Props = {
  url: string
}

const listStyle = css`
  list-style: none;
  padding: 0;
  li {
    padding: 10px;
    border-bottom: 1px solid #ddd;
  }
`

const HomePage = ({ url }: Props) => {
  const [history, setHistory] = useState<string[]>([])

  useEffect(() => {
    const storedHistory = JSON.parse(localStorage.getItem('history') || '[]')
    const newHistory = [...storedHistory, url]

    localStorage.setItem('history', JSON.stringify(newHistory))
    setHistory(newHistory)
  }, [url])

  return (
    <div>
      <h1>閲覧履歴</h1>
      <ul css={listStyle}>
        {history.map((url, index) => (
          <li key={index}>{url}</li>
        ))}
      </ul>
    </div>
  )
}

export default HomePage

これにより、閲覧履歴リストにパディングが追加され、リスト項目間に罫線が引かれます。Emotion は非常に強力な CSS-in-JS ライブラリで、JavaScript の全機能を使って CSS を記述できます。

以上が、Next.js と TypeScript を用いた、Web Storage API を使って閲覧履歴を表示する一連の流れです。

Next.js と TypeScript で、ユーザーの閲覧履歴を表示する方法