👋

jotaiとdexieを一緒に使う

2024/12/01に公開

jotaiとは?

https://jotai.org/
簡単にstateを扱えるようになるライブラリです。

とても使いやすいです。

dexieとは?

https://dexie.org/

indexedDBのラッパーです。
ブラウザ内でDBを扱うとき、5MBを超える場合はindexedDBを利用するのですが、それを簡単に扱えるようにしているラッパーがdexieです。

Let's put it together!!

まずは保存したい型を作ります。

account-model.ts
type Account = {
  id: string
  apiKey: string
  properties: Property[]
}

type Property = {
  
  propKey: string
  propertyName: string
  rooms: Room[]
}

//Roomの型定義

次にそれを扱うDBのJotaiを定義します。

account-database.ts

const accountDBAtom = atom((get) => {
  const db = new Dexie("account") as Dexie & {
    account: EntityTable<Account, "id">
  }
  db.version(1).stores({
    account: "++id,apiKey,properties"
  })
  return db
})

const baseAccountAtom = atom<Account>({} as Account)

const INIT_ACCOUNT = Symbol("INIT_ACCOUNT")

const accountAtom = atom(
  (get) => get(baseAccountAtom),
  (get, set, action) => {
    const db = get(accountDBAtom)

    if (action === INIT_ACCOUNT) {
      const observable = liveQuery(() => db.account.toArray())
      const sub = observable.subscribe((accounts) => {
        // console.log("accounts", accounts)
        set(baseAccountAtom, accounts[0])
      })
      return sub
    }
  }
)

accountAtom.onMount = (set) => {
  const sub = set(INIT_ACCOUNT)
  return () => sub.unsubscribe()
}
component.tsx

const AccountComponent: React.FC = () => {
    //ここでAtomを購読する
    const [account] = useAtom(accountAtom)

気をつけること

  • useLiveQueryはコンポーネント内でしか扱えないのでliveQueryを使う
  • onMountで初期化
  • 初期化時にサブスクリプションを作るようにする。

使い方など間違えていたらご指摘いただけると幸いです。

Discussion