🐈

セッションストレージのidから該当する値を取得したい場合

2024/12/14に公開

セッションストレージのidから該当する値を取得したい場合

今回はreduce()を使用した例です。
セッションストレージに値が無ければ、DBの値を取得できる設計になっています。
もっといい実装方法もあると思いますが、今回は開発を引き継いだ都合上こうなりました。

コードを先に記載します。

  const organizationOptions = organizationData.result.reduce((acc, org) => {
    acc[org.org_id] = org.org_name;
    return acc;
  }, {} as Record<number, string>);

まずデータを取得します。

  const { data: organizationData } = useSWR(
    {
      url: `getOrganizationListData`,
    },
    fetcher<OrganizationListData[]>,
  );

私はuseSWRを使用しましたが、async/awaitでももちろん取得できるので、お好きな方を使ってください。
fetcher<OrganizationListData[]> の<>は型を指定しています。
[]はこれが配列だよと教えています。
ちょっとカスタムしてしまっているので、皆さんは公式サイトから基本の使い方を参照して使用してください。
https://swr.vercel.app/ja

取得データのイメージ

[
  { org_id: 1, org_name: "組織名1" },
  { org_id: 2, org_name: "組織名2" }
]

処理結果:

acc[1] = "組織名1";

この時点で acc は以下のようになります:

{
  1: "組織名1"
}

acc[org.org_id] = org.org_name; に関して
オブジェクトのプロパティにアクセスする方法
JavaScriptでは、オブジェクトのプロパティにアクセスする方法として以下の2つがあります:

  1. ドット記法obj.key
  2. 括弧記法obj[key]

organizationData.org_id をキーにして動的に値を設定する場合、ドット記法は使えず、括弧記法が必要です。

**{} as Record<number, string>**に関して
初期値として空のオブジェクトを指定し、このオブジェクトの型を「キーが数字で、値が文字列のオブジェクト」と明示しています。

これでidと一致した組織名の一覧を取得できる関数が完成です。
そもそも組織名もデータから取得して表示すればいいのですが、「不要なデータを取得する必要はない」というPJリーダーの意向によりこうなりました。
個人的には組織名もデータから取得して表示の方が楽だったので、モヤっとしました。
(モヤットボールを知ってる方向けのネタ)

ここはセッションストレージからデータを取得する方法について記載しています。

//storageKeyはセッションストレージにデータを保存する際に使用しました。
//データを取得する時にも使用するので、ここで記載しましたが、親で管理すると楽です。
  const storageKey = getStorageKey({
    pageName: 'coachReferee',
    type: 'create',
  });
  
  const rawData = sessionStorage.getItem(storageKey);
  const parsedData: CoachRefereeResponse | null = rawData ? JSON.parse(rawData) : null;
  const coachingHistories = parsedData?.coachingHistories || [];

ここではセッションストレージのキーを指定します。
キーはcoachReferee-createという値になります。
JSON.parseでオブジェクトに変換します。
その後は皆さん大好きmapで展開していくだけです。

  return (
    <div>
      <h2 className='text-lg md:text-xl font-bold'>指導履歴</h2>
      <table className='text-nowrap mb-5'>
        <thead className='[&_th]:pb-2 [&_th]:w-52 [&_th]:text-left [&_th]:text-xs md:[&_th]:text-sm [&_th]:font-normal'>
          <tr className='border-b border-b-border '>
            <th>開始日</th>
            <th>終了日</th>
            <th>団体名</th>
            <th>スタッフ種別</th>
          </tr>
        </thead>
        <tbody className='[&_td]:pt-2 [&_td]:pr-2 [&_td]:text-xs md:[&_td]:text-sm [&_td]:font-normal [&_td]:max-w-[50px] [&_td]:text-ellipsis [&_td]:overflow-hidden'>
          {coachingHistories.map(
            (history: CoachRefereeResponse['coachingHistories'][number]) => (
              <tr key={history.orgCoachingHistoryId}>
                <td>{formatDate(history.startDate, 'yyyy/MM/dd')}</td>
                <td>{formatDate(history.endDate, 'yyyy/MM/dd') || '現在'}</td>
                <td>{organizations[history.orgId]}</td>
                <td>{staffTypeOptions[history.staffTypeId]}</td>
              </tr>
            ),
          )}
        </tbody>
      </table>
    </div>
  );

Discussion