見出し画像

コメントサービスを実現する際に意識するデータ構造について

こんにちわ。nap5です。


コメントサービスを実現する際に意識するデータ構造についてサンプルとして紹介してみます。


コメントデータモデルを中心にサービスを考えるといい感じになるので、記事にしてみました。


元ネタは以下のデモになります。Reduxを使ったことがないので、今回はRecoilで実現してみました。


コメントのUIですが、引用リツイートのような構成にしてみました。
いわゆるインデントをつけるものだと幅がだんだん狭くなってしまいますので、リツイートの形式でやってみました。

Zennとかのコメントタイムラインはデータ構造は今回と同じ気はしますが、表示する際に少し工夫を入れているようです。


Product HuntもそのようなUIになっています。



デモコードです。


デモサイトです。

DBはSupabaseを使ってみました。RLSなどはしていないので、アドホックになります。なので、興味がある方は悪用厳禁でデモ用でお願いいたします。



実装する点でポイントになるのは以下になります。

  • Map型を使ってコメントID単位でアクセスできるデータ構造をサブとして用意する

  • 一覧表示する際はvisitメソッドなどを使ってフラット化する

    • visitメソッドに関してはunistから提供されているようなものをイメージしています

  • 削除機能は論理削除で代替する

    • フラグ制御になります

  • 隠す機能も論理削除で代替する

    • フラグ制御になります


実現するにあたり以下のライブラリが重宝します。


データ構造は以下になります。

import { Simplify, SnakeCasedProperties } from 'type-fest'

export type Comment = {
  id: string
  type: 'root' | 'child'
  parentId: string | null
  author: string
  text: string
  isHidden: boolean
  isDeleted: boolean
  children: Comment[]
  createdAt: string // 2023/5/7 12:42:36
  updatedAt: string // 2023/5/7 12:42:36
}

export type CommentWithSibling = Simplify<
  Comment & {
    depth: number
    siblingIndex: number | null
  }
>

export type CommentForDB = SnakeCasedProperties<Comment>


自作しようと考えている方はこれを参考にチャレンジしてみてもいいかもですね。


すでに類似のサービスはいくつかあるので、それらを導入でもいいかもです。



簡単ですが、以上です。


この記事が気に入ったらサポートをしてみませんか?